Let a is global variable of type A or field of current object of type A.
Is the following code thread safe?
if a is B {
a.methodOfB()
}
and
if a != null {
a.methodOfA()
}
a could be changed in other thread and these checks might not help.
Does Kotlin save checked value of a to local variable?
In Swift it’s done slightly in other way and I know that this is thread safe in Swift:
if let a = a { // null check and assignment to local variable `a`
a.methodOfA()
}
and
if let a = a as? B { // safe cast, check for null and assignment to local variable a. also it can be done with `where` construct, but it doesn't matter here
a.methodOfB()
}
var a: String? = null
fun useA() {
if (a != null) {
println(a.length)
^ Error:(8, 17) Kotlin: Smart cast to 'kotlin.String' is impossible,
because 'a' is a mutable property that could have been
changed by this time
}
}
fun isA() {
if (a is String) {
println(a.length)
^ Error:(8, 17) Kotlin: Smart cast to 'kotlin.String' is impossible,
because 'a' is a mutable property that could have been
changed by this time
}
}
The closest to what you want is probably this:
val ta = a
if (ta != null) {
println(ta.length)
// more statements working on ta
}
You can’t do it as compact as in your Swift example because you can’t declare variables in if statements. You also can’t use braces like this (val ta = a)?.let { ... }
You can accomplish something very close to the Swift version in Kotlin. You can either re-use the name of the outer variable as the name of the inner scoped one, or you can rename it, or you can use the implicit it reference:
a?.let { a ->
a.methodOfA()
}
a?.let { localA ->
localA.methodOfA()
}
a?.let {
it.methodOfA()
}
(a as? B)?.let { a ->
a.methodOfB()
}
(a as? B)?.let { b ->
b.methodOfB()
}
(a as? B)?.let {
it.methodOfB()
}