Kotlin .let {} null安全假设错误

时间:2017-04-26 11:12:12

标签: kotlin kotlin-null-safety

使用.let { }函数时,我注意到执行以下操作时:

bucket?.assignedVariantName.let {
        bucket?.determineVariant()  <-- guarantee safety for bucket
}

在这种情况下,您必须保证存储桶的安全,即bucket?.bucket!!,而使用?.let已确保无效安全性,然后我注意到执行以下操作:

bucket?.assignedVariantName?.let { <-- added safety check for property 
        bucket.determineVariant()  <-- doesn't need to guarantee safety for bucket
}

虽然在存储桶的属性上使用let而不是直接在存储桶上使用,但我想知道这是故意还是Kotlin插件中的错误(在这种情况下我在Android Studio中遇到过这种情况)

其他信息是,在这种情况下,存储区为local val,而assignedVariantName是可空的变量。

val bucket: T? = ...

1 个答案:

答案 0 :(得分:17)

这是预期的行为。 .let { ... } function定义为

inline fun <T, R> T.let(block: (T) -> R): R = block(this)

T可以是可空类型,let可以在空接收器上调用,null.let { }是有效代码。

现在看一下这两个电话:

  • bucket?.assignedVariantName.let { ... }

    此处,无论接收方let是否为空,始终都会调用bucket?.assignedVariantName

    有可能bucket?.assignedVariantName为空,因为bucket为空 - 然后null只是传递给let,并且使用它绝对不安全bucket块内的let

    (runnable example of the case)

  • bucket?.assignedVariantName?.let { ... }

    在这种情况下,仅当接收方let不为空时才调用bucket?.assignedVariantName,要求bucket不为空且其assignedVariantName不为空。此要求可以安全地在bucket块中使用let