Hi, I just ran into this quirky behavior combining...
# getting-started
g
Hi, I just ran into this quirky behavior combining if statement as an expression and elvis operator :
Copy code
val nonNullVal = 
if(condition1) { 
    someOperation.get() // null 
} else if (condition2) { 
    someOperationTwo.get() // null 
} else { 
    null 
} ?: defaultVal
When condition 1 is true our
nonNullVal
evaluates to
null
. When condition 1 is false and condition 2 is true our
nonNullVal
evaluates to
defaultVal
What is happening? X_x I would just like to get a grasp of what is going on internally. Any help is appreciated! Thanks!
j
my guess is that everything after the first else is like its wrapped in {}
I can't find a lot of docs about else-if seems to me every else-if is really just
else {if...}
so what happens here is that you have
Copy code
if (condition1) { block } else expression
where
expression
is
Copy code
if (condition2) { block } else { block } ?: defaultVal
g
I was just typing this but you were faster 😄 : So what I thought was
Copy code
val nnv = 
( if(a) null 
else if(b) null 
else null )
?: defaultVal
is actually
Copy code
val nnv = if(a) null else (if(b) null else null ?: defaultVal)
?! That explains it! Thanks you so much! I’m glad I asked 😃
e
try using a single
when
to get your desired behavior,
Copy code
when {
    condition1 -> ...
    condition2 -> ...
    else -> null
} ?: defaultVal
the precedence in the grammar here does seem confusing, though. it may be worth filing a YouTrack issue to ask if they can modify the grammar to account for if-else chains
I've brought it up in https://kotlinlang.slack.com/archives/C0B9K7EP2/p1651041143051719, and in the meanwhile, you can either use
when
or
Copy code
inline fun <R> runIf(cond: Boolean, then: () -> R): R? = if (cond) then() else null

val nonNullVal = runIf(condition1) {
    someOperation.get() // null
} ?: runIf(condition2) {
    someOperationTwo.get() // null
} ?: defaultVal
as borrowed from https://youtrack.jetbrains.com/issue/KT-43712
g
Thanks! For now I’ll just call it a TIL and carve it onto my heart to use
when
expression instead of
else if
whenever possible.