Reputation: 3155
I started to learn Kotlin recently. One thing I can't get my head around is the null check blocks. The following statement is considered unsafe, and the compiler won't allow you to compile this.
var testVar: String? = null;
// if (testVar != null )
{
// Doing some work....
println(testVar.length)
}
But when you uncomment the if
line, everything works. This seems great.
But what if // Doing some work....
is computationally expensive and another thread changes the value of testVar
to null
while this thread is in // Doing some work
line? In this scenario:
Upvotes: 0
Views: 191
Reputation: 134714
In your initial example, is your var
local to a function? For example:
fun doStuff() {
var testVar: String? = null
if (testVar != null) {
println(testVar.length)
}
}
In this case, no other scope has reference to testVar
so nothing else can change it. However, if the var
is a class property, i.e.
class MyClass {
var testVar: String? = null
fun doStuff() {
if (testVar != null) {
println(testVar.length)
}
}
}
This will fail to compile as testVar
could have been set to null by another thread in between the check and the usage.
Going further, if you try to be tricky:
fun doStuff() {
var testVar: String? = null
fun trickyFunction() {
testVar = null
}
if (testVar != null) {
trickyFunction()
println(testVar.length)
}
}
The compiler will fail as your variable is captured by a changing closure. So in general, if you are able to use the variable via a smart-cast to non-null, you should not have to worry about any potential for NPEs.
For the second scenario (var properties) it is preferable to rely on .let
to capture an immutable reference to the current value, i.e.
testVar?.let { capturedTestVar ->
println(capturedTestVar.length)
}
Upvotes: 3