智能转换为“types”是不可能的,因为“variables”是一个可以改变的可变属性
Kotlin新手问道: “为什么下面的代码不能编译?” :
var left: Node? = null fun show() { if (left != null) { queue.add(left) // ERROR HERE } }
智能投到“节点”是不可能的,因为“左”是一个可变的属性,可能已经改变了这个时间
我得到left
是可变的variables,但我显式检查left != null
和left
是Node
types,为什么不能聪明地转换为该types?
我怎样才能解决这个优雅? 🙂
在执行n.left != null
和queue.add(n.left)
另一个线程可能n.left
的值n.left
为null
。
要解决这个问题,你有几个选择。 这里有一些:
-
使用智能转换使用本地variables:
val left = n.left if (left != null) { queue.add(left) }
-
请使用以下安全呼叫之一:
n.left?.let { left -> queue.add(left) } n.left?.let { queue.add(it) } n.left?.let(queue::add)
-
使用Elvis操作符 跳转到封闭
while
循环的下一步:queue.add(n.left ?: continue)
除了mfulton26的答案之外,还有第四种选择。
通过使用?.
运算符可以调用方法以及字段而不用处理let
或使用局部variables。
上下文的一些代码:
var factory: ServerSocketFactory = SSLServerSocketFactory.getDefault(); socket = factory.createServerSocket(port) socket.close()//smartcast impossible socket?.close()//Smartcast possible. And works when called
它与方法,领域和所有其他的东西,我试图让它的工作。
所以为了解决这个问题,不必使用手动转换或使用局部variables,你可以使用?.
调用方法。
作为参考,这在Kotlin 1.1.4-3
中进行了测试,但也在1.1.51
和1.1.60
进行了测试。 不能保证它可以在其他版本上运行,这可能是一个新function。
使用?.
运算符不能用于你的情况,因为它是一个通过variables,这是问题。 Elvis算子可以作为一个替代方案,也可能是最少量的代码。 不用continue
使用,也可以使用return
。
使用手动铸造也可以是一个选项,但这不是零安全的:
queue.add(left as Node);
意思是如果在不同的线程上左改变了,程序将会崩溃。