我是Kotlin的新手,我不知道为什么编译器抱怨这段代码:
data class Test(var data : String = "data")
fun test(){
var test: Test? = Test("")
var size = test?.data.length
}
编译器向test?.data.length
投诉,它说我应该这样做:test?.data?.length
。但数据变量为String
,而不是String?
,所以我不明白为什么在我想检查长度时必须放?
。
答案 0 :(得分:10)
表达式test?.data.length
相当于(test?.data).length
,test?.data
部分可以为空:它是test.data
或null
。因此,获取length
并非空安全,而是应再次使用safe call operator:test?.data?.length
。
可空性通过整个调用链传播:你必须将这些链写为a?.b?.c?.d?.e
(再次,相当于(((a?.b)?.c)?.d)?.e
),因为,如果其中一个左边部分为null ,其余的调用无法执行,就像值不为null一样。
答案 1 :(得分:3)
如果您不想在调用链的每个非可空组件之前使用安全调用,则可以使用标准扩展函数run
将第一个安全调用的结果转换为新变量或let
:
// `this` is non-nullable `Test` inside lambda
val size = test?.run { data.length }
// or: `it` is non-nullable `Test` inside lambda
val size = test?.let { it.data.length }
请注意,此处size
仍然可以为Int?
。