持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第23天,点击查看活动详情
什么是作用域
作用域函数是在对象的上下文中执行代码块的函数,Scope 函数为我们提供了一种为对象提供临时作用域的方法
let
上下文对象可用作参数 ( it)。返回值是 lambda 结果。
private var x: Int? = null
fun main() {
if (x != null) {
// 编译器提示:智能转换为“Int”是不可能的,因为“x”是一个可变属性,此时可能已更改
val y = x + 1
}
}
那么问题来了,为什么当我们已经对x进行了空校验,依旧会提示错误呢??原因是我们声明x为全局变量时,我们不知道块内部是否有另一个线程同时操作当前这个全局变量。也就是说当x!=null且执行val y = x + 1之前时,还有另外一个线程将x置为null。这对于空安全的kotlin语言来说是不允许的,如何解决呢?
我们可以使用非空断言运算符!!,但是这是一个不太好的方法,毕竟x真的可能为空,只是解决了编译器的问题而已,当实际运行过程中如果x为空了,那么我们的程序就会崩溃。
所以我们推荐使用:
val y = x?.let{
it + 1
}
那么问题又来了,为什么我们推荐的这种方式没有问题呢??x?它确保在x不等于 null 之前不会执行 let 块,这就是问号的含义。.let{ } 函数在这里所做的是在x值不等于 null 时执行,当我们开始执行时,x我们将使用it关键字作为替代。换句话说就是当x不为空时,做执行的是it,而不是x,所以无论x是否被其他线程所修改都不会影响到我们的it关键字。所以在这种空校验执行逻辑的情况下我们推荐使用let函数。
为了保障我们的程序健壮性我们还可以为null情况分配其他逻辑:
val y = x?.let{
val y = it + 1
}?:{
2
}
还有一个不太重要的点,在上面的示例中let总是返回其块内的最后一行,你会发现y类型是Any,但如果我们y在的后面添加:Int时,结果变量的类型将变为Int。