В вашем первоначальном примере ваш var
является локальным для функции? Например:
fun doStuff() {
var testVar: String? = null
if (testVar != null) {
println(testVar.length)
}
}
В этом случае ни одна другая область не имеет ссылки на testVar
, поэтому ничто другое не может ее изменить. Однако, если var
является свойством класса, то есть
class MyClass {
var testVar: String? = null
fun doStuff() {
if (testVar != null) {
println(testVar.length)
}
}
}
Это не удастся скомпилировать, поскольку testVar
мог быть установлен равным нулю другим потоком между проверкой и использованием.
Идем дальше, если вы пытаетесь быть хитрым:
fun doStuff() {
var testVar: String? = null
fun trickyFunction() {
testVar = null
}
if (testVar != null) {
trickyFunction()
println(testVar.length)
}
}
Компилятор потерпит неудачу, так как ваша переменная захвачена изменяющимся замыканием. Поэтому, в общем, если вы можете использовать переменную посредством умного приведения к ненулевому значению, вам не нужно беспокоиться о потенциальной возможности NPE.
Для второго сценария (свойства var) предпочтительно полагаться на .let
для захвата неизменной ссылки на текущее значение, т. Е.
testVar?.let { capturedTestVar ->
println(capturedTestVar.length)
}