Kotlin "let{}" 不提供智能转换
Kotlin "let{}" Doesn't Provide Smart Cast
刚刚学习了 Kotlin Nullable
类型和 let{}
函数,它取代了 if (xx != null) {}
操作。
但是让我感到困惑的一件事是,我们都知道并且我认为编译器应该知道当我们使用let{}
时,variable/object谁在调用这个函数可能是空的,但是编译器仍然要求我添加安全调用运算符“?”在变量名之后,而不是像在 if (xx != null) {}
中那样提供 Smart Cast。为什么?
我的一段代码:
fun main() {
var number1: Int? = null
//val number2 = number1.let { it + 1 } ?: 10 //doesn't work, not quite "smart"
val number2 = number1?.let { it + 1 } ?: 10 //works, must have "?"
println(number1)
println(number2)
}
您已经在评论中得到了答案,但只是为了解释 ?
事情...
Kotlin 允许您通过在调用前添加 ?
来对可为空的变量和属性进行空安全调用。你也可以通过做
来链接它
nullableObject?.someProperty?.someFunction()
计算 nullableObject
,而 如果 为非空,则计算下一位,否则整个表达式计算为 null
。如果链的任何部分评估为 null,则整个表达式 returns null.
所以它有这种短路效果,如果你不能将整个链评估为非空结果,你可以使用 elvis 的“if null”运算符来创建一个默认值:
nullableObject?.nullableProperty?.someFunction() ?: defaultAction()
一旦你在链中引入空检查,你必须在之后的每次调用中添加它——它基本上传播前一位的结果,或者它解析到的 null
,所以每一步都有空检查
let
块只是一个作用域函数 - 你可以在一个值上使用它,所以你可以 运行 一些代码使用该值作为参数或接收器(变量或 this
基本上)。它还具有创建一个新的临时局部变量来保存该值的副作用,因此如果原始变量是 var
则该值是否更改并不重要,因为您的 let
代码没有引用到那个变量了。
因此,它对进行一次空值检查很有用,而不必担心在使用它时基础值可能变为空值:
nullableVar?.let { it.definitelyIsNotNull() }
编译器会识别并智能地将其转换为非空类型。 if (nullableVar != null)
检查不能保证下一行执行时 nullableVar
不会为空。
刚刚学习了 Kotlin Nullable
类型和 let{}
函数,它取代了 if (xx != null) {}
操作。
但是让我感到困惑的一件事是,我们都知道并且我认为编译器应该知道当我们使用let{}
时,variable/object谁在调用这个函数可能是空的,但是编译器仍然要求我添加安全调用运算符“?”在变量名之后,而不是像在 if (xx != null) {}
中那样提供 Smart Cast。为什么?
我的一段代码:
fun main() {
var number1: Int? = null
//val number2 = number1.let { it + 1 } ?: 10 //doesn't work, not quite "smart"
val number2 = number1?.let { it + 1 } ?: 10 //works, must have "?"
println(number1)
println(number2)
}
您已经在评论中得到了答案,但只是为了解释 ?
事情...
Kotlin 允许您通过在调用前添加 ?
来对可为空的变量和属性进行空安全调用。你也可以通过做
nullableObject?.someProperty?.someFunction()
计算 nullableObject
,而 如果 为非空,则计算下一位,否则整个表达式计算为 null
。如果链的任何部分评估为 null,则整个表达式 returns null.
所以它有这种短路效果,如果你不能将整个链评估为非空结果,你可以使用 elvis 的“if null”运算符来创建一个默认值:
nullableObject?.nullableProperty?.someFunction() ?: defaultAction()
一旦你在链中引入空检查,你必须在之后的每次调用中添加它——它基本上传播前一位的结果,或者它解析到的 null
,所以每一步都有空检查
let
块只是一个作用域函数 - 你可以在一个值上使用它,所以你可以 运行 一些代码使用该值作为参数或接收器(变量或 this
基本上)。它还具有创建一个新的临时局部变量来保存该值的副作用,因此如果原始变量是 var
则该值是否更改并不重要,因为您的 let
代码没有引用到那个变量了。
因此,它对进行一次空值检查很有用,而不必担心在使用它时基础值可能变为空值:
nullableVar?.let { it.definitelyIsNotNull() }
编译器会识别并智能地将其转换为非空类型。 if (nullableVar != null)
检查不能保证下一行执行时 nullableVar
不会为空。