Kotlin新手问:“为什么下面的代码不能编译?”:

var left: Node? = null
    
fun show() {
    if (left != null) {
        queue.add(left) // ERROR HERE
    }
}

智能转换为'Node'是不可能的,因为'left'是可变的 此时可以更改的属性

我得到left is mutable变量,但我显式检查left != null left是Node类型,为什么它不能被智能转换为这种类型?

我该如何优雅地解决这个问题?


当前回答

Change var left: Node?= null to lateinit var left:节点。问题解决了。

其他回答

在执行left != null和queue.add(left)之间,另一个线程可能已经将left的值更改为null。

要解决这个问题,您有几个选择。以下是一些例子:

使用智能强制转换的局部变量: Val节点= left If (node != null) { queue.add(节点) } 使用一个安全的调用,例如以下之一: 离开吗?。让{node -> queue.add(node)} 离开吗?。Let {queue.add(it)} 离开?报价吧(队列::添加) 使用带有return的Elvis操作符提前从封闭函数返回: 队列中。Add (left ?: return) 注意,break和continue可以类似地用于循环中的检查。

要使属性具有Smart Cast,属性的数据类型必须是包含您想要访问的方法或行为的类,而不是属性为超类的类型。


例如在Android上

Be:

class MyVM : ViewModel() {
    fun onClick() {}
}

解决方案:

From: private lateinit var viewModel: ViewModel
To: private lateinit var viewModel: MyVM

用法:

viewModel = ViewModelProvider(this)[MyVM::class.java]
viewModel.onClick {}

GL

这招对我很管用: private lateinit var varName:字符串

尝试使用非空断言操作符…

queue.add(left!!) 

1)你也可以使用lateinit如果你确定你将在onCreate()或其他地方进行初始化。

使用这个

lateinit var left: Node

而不是这个

var left: Node? = null

2)还有其他使用方法!!当你像这样使用它时,变量就结束了

queue.add(left!!) // add !!