Reputation: 1060
Faced an interesting case when Elvis Operator ?:
misconducts.
Imagine having something like this
base64ToBmp(str)?.let { <1> } ?: run { <2> }
and see that on some old phones and emulators <1>
and <2>
code was invoked.
<1>
was displaying bitmap
<2>
was displaying error
This was acting like Bitmap failed to parse.
Anyone seen such behavior? Is there a logical explanation?
Upvotes: 1
Views: 247
Reputation: 14255
let
returns the value of the specified function block.
So the logical explanation is that <1>
returns null
. In that case the whole expression base64ToBmp(str)?.let { <1> }
becomes null
and the right hand side of the elvis operator (i.e. run { <2> }
) will be evaluated.
A very simplified way of reproducing it would be:
"foo"?.let { print("<1>"); null } ?: print("<2>")
// Prints <1><2>
Depending on your actual use case, apply
or also
(which both return the context object itself) might be suitable (note that for apply
the object reference is passed as this
instead of it
):
"foo"?.apply { print("<1>"); null } ?: print("<2>")
// Prints <1>
Upvotes: 6
Reputation: 6988
@Marvin's answer is correct, if you want to reproduce the scenario you could try this piece of code:
fun main() {
fun someMethod(param: String?) = param
fun letBlock(param: String): String? {
println("<1>")
return null
}
someMethod("some param")?.let(::letBlock) ?: run {
println("<2>")
}
}
The output is:
<1>
<2>
Upvotes: 2