我正在学习Android,我也在学习Kotlin。
在编写Android代码时,我很好奇在let函数中使用let。
MainActivity.kt
class MainActivity : AppCompatActivity() {
private var curFrag: Fragment? = null
curFrag = fm.primaryNavigationFragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// curFrag?.let { transaction.hide(curFrag) } // error.
curFrag?.let { transaction.hide(it) }
}
}误差
Smart cast to 'Fragment' is impossible, because 'curFrag' is a mutable property that could have been changed by this time在let()的lambda表达式中,T为curFrag,类型为Fragment?。
T(curFrag)可以用it代替。
但是当我使用curFrag而不是it时,IDE显示了一条错误消息。
后来,当我检查it的类型时,它是Fragment? --它不是Fragment类型。
老实说,我不太明白。
我不知道为什么它是自动的smart cast,应该只用于immutable variables。
发布于 2021-05-22 02:23:33
let函数基本上创建了一个新变量,其值与您调用它的值相同,因此它并不是真正聪明的--转换原始属性。
如果使用?.let,如果值为null,甚至不会调用let。安全调用意味着正在调用的接收方let开始时不是一个可为空的值,因为否则根本不会调用let。it on let只是对它被调用的引用。
实际上,它在概念上类似于智能转换。实际上没有一种方法可以编写类似的Kotlin代码来执行?.let所做的工作,因为?.安全调用是一个没有扩展形式的特殊运算符。
发布于 2021-05-21 20:49:57
Kotlin是一种空安全语言,它试图从代码中消除所有可能的空引用。您可以对变量执行空性检查,然后可以像这样使用它
if(curfrag != null) { transaction.hide(curFrag)
这也只有在变量curfrag是不可变的(这意味着在检查和使用之间没有修改的局部变量,或者成员val有一个后备字段且不可覆盖)时才能工作,因为否则可能会发生curfrag在从其他线程进行检查后更改为null。
但是,带?.的安全调用let总是给出非空的结果,安全调用操作符?.所做的是,它只执行跟随它的任何操作,只有当变量不是- null时,否则它返回null。
它与所有可变类型或成员var一起工作,它只检查一次null,然后提供结果。如果值是非空的,则执行定义的操作,否则跳过它。it指的是非空值的副本。
所以当你这么做的时候
curFrag?.let { transaction.hide(curFrag) }
当您直接传递一个可空值时,curFrag可以是空的。
但在这种情况下
curFrag?.let { transaction.hide(it) }
它只在非空值的情况下传递值。
https://stackoverflow.com/questions/67643464
复制相似问题