10

我是 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。但是 data 变量是String, not String?,所以我不明白为什么我?要检查长度时必须放 。

4

2 回答 2

11

该表达式test?.data.length等价于(test?.data).length,并且该test?.data部分可以为空:它是test.datanull。因此,获取它的 不是空安全的length,而是您应该再次使用安全调用运算符test?.data?.length

可空性通过整个调用链传播:您必须将这些链写为a?.b?.c?.d?.e(再次等同于(((a?.b)?.c)?.d)?.e),因为如果左侧部分之一为空,则无法执行其余调用,就好像值不为空。

于 2017-02-03T13:28:11.480 回答
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?

于 2017-02-03T14:37:10.550 回答