Thank you answer, It’s my problem.
My focus is not about distribution, but about smart cast.
If we delete function b in this case, we well get a compile error in methodA: Error:(27, 13) Kotlin: Reference has a nullable type 'B?', use explicit '?.invoke()' to make a function-like call instead
But this error won’t be in functionA.
Actually my question is why does smart cast only work in functionA? Is it because b is a class properties in methodA?
functionA acts normal: b cannot change and it knows it.
methodA accesses a field. Globally speaking, fields can change.
val t : Double get() = rand().takeIf{ it > 0.5 }
In this case, however, the field cannot change as it has no custom getter.
It seems almost all functions are aware of this:
you can call normal functions on b;
you can access b by their operator overloading (tried get and unaryMinus);
The only one (I’m aware of) which does not about this is invoke: you can call it as a function, but you can’t invoke b.
This seems indeed like a bug.
class B {
operator fun invoke() = Unit
operator fun get(name : String) = 5
fun test() = Unit
}
class A(val b: B?) {
fun methodA() {
if (b != null) {
//allowed
b.invoke()
b.test()
b["I"]
//not allowed
b()
}
}
}