Reputation: 1207
According to the Kotlin docs, the ?. operator represents a 'safe call', meaning that if it's used in a chain of method calls, the entire chain will return null if the value of whatever it's used on is null.
But what about if it's used on the left side of an assignment? Since the left side isn't the side that's 'returning' anything it seems like it probably has a different effect. Here's an example of what I'm talking about:
val myObj = SomeObj()
myObj?.property = SomeClass.someFunc() // What does ?. do in this context?
Upvotes: 28
Views: 3513
Reputation: 147901
It means that if one of the safe calls on the left-hand side fails (i.e. its receiver is null), then the whole assignment is skipped, and the expression on the right-hand side is not evaluated at all.
val nullable: Container? = null
nullable?.x = f() // f is not called
Upvotes: 30
Reputation: 30676
I'm seeing a fun question & answer in Kotlin just now. Even if the answer is very nice, but I want to clarify it in more detailed.
The assignment expression below:
myObj?.property = SomeClass.someFunc()
is transformed to Java bytecode by Kolin as below:
val it = myObj;
if(it != null){
it.property = SomeClass.someFunc();
}
so there is no problem in multiple threads. It still works fine and I have tested it on github. But it will result in the Thread Interference problem, which means it will modify the property
on different references when myObj
is changed.
Except the assignment expression can be short-circuited, others also can be short-circuited. For example:
val array:Array<Any>? = null;
// v--- short-circuited
array?.set(0,SomeClass.someFunc());
// ^--- never be called
Upvotes: 3