我最近开始学习Kotlin。我无法理解的一件事是空检查块。以下语句被认为是不安全的,并且编译器不允许您对其进行编译。
var testVar: String? = null;
// if (testVar != null )
{
// Doing some work....
println(testVar.length)
}
但是当您取消注释if
行时,一切正常。这看起来很棒。
但是如果 // Doing some work....
在计算上很昂贵,而另一个线程在testVar
行中,则另一个线程将null
的值更改为// Doing some work
怎么办? ?在这种情况下:
答案 0 :(得分:3)
在您的最初示例中,您的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
在检查和使用之间可能已被另一个线程设置为null。
走得更远,如果您尝试棘手的话:
fun doStuff() {
var testVar: String? = null
fun trickyFunction() {
testVar = null
}
if (testVar != null) {
trickyFunction()
println(testVar.length)
}
}
编译器将失败,因为您的变量被更改的闭包捕获。因此,通常,如果您能够通过智能广播将变量使用为非空值,则不必担心NPE的任何潜在可能性。
对于第二种情况(可变属性),最好依靠.let
来捕获对当前值的不变引用,即
testVar?.let { capturedTestVar ->
println(capturedTestVar.length)
}