Suppose I have the following code :
fun main() {
val userName: String? = "Dmitry" // line 1
userName?.takeLast(2)?.reversed() // line 2
userName?.plus("kotlin").plus("lang") // line 3
}
I can't get the reason for the usage of Elvis operator before reversed() - why it is not possible to use just . ? As I can see in doc takeLast() always provides String, not String?. The same scenario works for Line 3 in my example -> plus() always returns String so there is no need of Elvis before the Second plus() ?
Since there is a ?. before takeLast(), the resulting expression evaluates to a nullable String. Since userName could be null, takeLast() might not even be called and you would just have null going into the takeLast() call.
In your last line you are calling an extension function defined for a nullable String receiver, so it doesn’t need to be conditionally called. It’s defined as fun String?.plus so it can be called directly on a nullable input.
By the way, ?. is not called the Elvis operator. It is called the safe call operator. The Elvis operator is ?: and does something different.
From the specs:
a?.cis exactly the same aswhen (val $tmp = a) { null -> null else -> { $tmp.c } }
In other words, userName?.takeLast(2)?.reversed() is the same as:
val $tmp1: String? = when (userName) {
null -> null
else -> userName.takeLast(2)
}
val $tmp2: String? = when ($tmp1) {
null -> null
else -> $tmp1.reversed()
}
// ...and so on.
The above expansion shows that each step on its own may return null, which means it is necessary to repeat ?..
As for .plus(), the first .plus() is String.plus(), whereas the second .plus() is String?.plus(). The latter would treat null as the string "null", but this is not the case with the first.
If userName is null, userName.plus() will call String?.plus(). It is only because of ?. that String.plus() is called instead. To apply the same aforementioned expansion:
val $tmp: String? = when (userName) {
null -> null
else -> userName.plus("kotlin") // String.plus()
}
$tmp.plus("lang") // String?.plus()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With