3 回答

TA貢獻1799條經驗 獲得超9個贊
在left != null和執(zhí)行之間,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可以從封閉函數(shù)中提前返回:
queue.add(left ?: return)
請注意,break并且continue可以類似地用于循環(huán)內的檢查。

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 !!
添加回答
舉報