4

使用该.let { }功能时,我注意到在执行以下操作时:

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

在这种情况下,您必须保证存储桶的安全性, bucket?.或者bucket!!在使用?.letthen 我注意到执行以下操作时已经保证了空安全性:

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

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

附加信息是,在这种情况下,bucket 是一个local valwhile assignmentVariantName 是一个可为空的 var。

val bucket: T? = ...
4

1 回答 1

17

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

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

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

现在看看这两个调用:

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

    在这里,let无论接收者是否bucket?.assignedVariantName为空,总是调用。

    有一种可能的情况bucket?.assignedVariantName是 is null 因为bucketis null —— thennull只是传入,在块内let使用绝对不安全。bucketlet

    (可运行的案例示例)

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

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

于 2017-04-26T11:20:31.500 回答