Smart cast to 'Type' is impossible, because 'variable' is a mutable property that could have been changed by this time
Between execution of left != null
and queue.add(left)
another thread could have changed the value of left
to null
.
To work around this you have several options. Here are some:
-
Use a local variable with smart cast:
val node = left if (node != null) { queue.add(node) }
-
Use a safe call such as one of the following:
left?.let { node -> queue.add(node) } left?.let { queue.add(it) } left?.let(queue::add)
-
Use the Elvis operator with
return
to return early from the enclosing function:queue.add(left ?: return)
Note that
break
andcontinue
can be used similarly for checks within loops.
1) Also you can use lateinit
If you sure do your initialization later on onCreate()
or elsewhere.
Use this
lateinit var left: Node
Instead of this
var left: Node? = null
2) And there is other way that use !!
end of variable when you use it like this
queue.add(left!!) // add !!
There is a fourth option in addition to the ones in mfulton26's answer.
By using the ?.
operator it is possible to call methods as well as fields without dealing with let
or using local variables.
Some code for context:
var factory: ServerSocketFactory = SSLServerSocketFactory.getDefault();
socket = factory.createServerSocket(port)
socket.close()//smartcast impossible
socket?.close()//Smartcast possible. And works when called
It works with methods, fields and all the other things I tried to get it to work.
So in order to solve the issue, instead of having to use manual casts or using local variables, you can use ?.
to call the methods.
For reference, this was tested in Kotlin 1.1.4-3
, but also tested in 1.1.51
and 1.1.60
. There's no guarantee it works on other versions, it could be a new feature.
Using the ?.
operator can't be used in your case since it's a passed variable that's the problem. The Elvis operator can be used as an alternative, and it's probably the one that requires the least amount of code. Instead of using continue
though, return
could also be used.
Using manual casting could also be an option, but this isn't null safe:
queue.add(left as Node);
Meaning if left has changed on a different thread, the program will crash.