3 回答
TA贡献1799条经验 获得超9个赞
在left != null和执行之间,queue.add(left)另一个线程可能将的值更改left为null。
要解决此问题,您有几种选择。这里有一些:
在智能转换中使用局部变量:
val node = left
if (node != null) {
queue.add(node)
}
使用安全呼叫,例如以下之一:
left?.let { node -> queue.add(node) }
left?.let { queue.add(it) }
left?.let(queue::add)
使用Elvis运算符和return可以从封闭函数中提前返回:
queue.add(left ?: return)
请注意,break并且continue可以类似地用于循环内的检查。
TA贡献1863条经验 获得超2个赞
除了mfulton26的答案中的第四个选项。
通过使用?.运算符,可以调用方法以及字段,而无需处理let或使用局部变量。
一些上下文代码:
var factory: ServerSocketFactory = SSLServerSocketFactory.getDefault();
socket = factory.createServerSocket(port)
socket.close()//smartcast impossible
socket?.close()//Smartcast possible. And works when called
它可以与方法,字段以及我尝试使其正常工作的所有其他事情一起使用。
因此,为了解决此问题,您不必使用手动强制转换或使用局部变量,而可以使用?.来调用方法。
作为参考,它在Kotlin中进行了测试1.1.4-3,但也在1.1.51和中进行了测试1.1.60。无法保证它可以在其他版本上使用,这可能是一项新功能。
?.在您的情况下,不能使用运算符,因为这是传递的变量。Elvis运算符可以替代使用,它可能是需要最少代码量的运算符。除了使用之外continue,return还可以使用。
也可以选择使用手动强制转换,但这不是null安全的方法:
queue.add(left as Node);
这意味着如果在其他线程上更改了left ,程序将崩溃。
TA贡献1784条经验 获得超2个赞
您也可以使用lateinitIf稍后在onCreate()其他地方进行初始化。
用这个
lateinit var left: Node
代替这个
var left: Node? = null
还有这样使用!!变量结尾的其他方式
queue.add(left!!) // add !!
添加回答
举报