// first piece of code start
var name1: String?
name1 = null
println(name1!!.length) // Unresolved reference: length
// first piece of code end
// second piece of code start
var name2: String? = null
println(name2!!.length)
// second piece of code end
When I hover my house over the "length" in the first piece of code, I get the message "Unresolved reference: length", and also "length" is in red. So, I figure out that the compiler already knows it is null and hence the message.
But doesn't the compiler already know that "name2" is also null? Why is not the length in the second piece of code not in red and there is no "Unresolved reference: length" message when I hover my mouse on the "length"?
The first piece of code doesn't even compile due to unresolved reference, but the second one does, and throws an exception.
Can someone explain why Kotlin compiler behaves in this way? I am using IntelliJ if it matters.
I don't have any formal confirmation or documentation to link to, but apparently, for the Kotlin compiler this is like:
var name1: String?; name1 = null - create a variable of type: String?, then assign a null to it (smart cast)var name2: String? = null - create a null value, then assign it to a variable of type: String?.As a result, in the first example the inferred type is null (technically, it is Nothing?) and in the second it is String?. The same happens in the opposite situation:
var name1: String?
name1 = "value"
println(name1.length) // allowed, `name1` is `String`
var name2: String? = "value"
println(name2.length) // not allowed, `name2` is `String?`
To be honest, I'm not a huge fan of this behavior. I see the logic in this, as in both cases the order of operations is conceptually different. But I don't see a reason to not infer/smart-cast the type and this behavior forces the developer to split a simple operation into two lines.
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