Kotlin .let {} нулевая безопасность предположительно ложная ошибка

При использовании .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 для свойства bucket, а не непосредственно для bucket, мне интересно, намеренно ли это или ошибка в плагине Kotlin (в этом случае я столкнулся с этим в Android Studio)

Дополнительная информация о том, что ведро в этом случае local val в то время как assignVariantName является допускаемой переменной var.

val bucket: T? = ...

1 ответ

Решение

Это ожидаемое поведение. .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 нуль, потому что bucket нуль - тогда null просто передается в letи это определенно не безопасно использовать bucket внутри let блок.

    (работоспособный пример кейса)

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

    В этом случае, let вызывается только если получатель bucket?.assignedVariantName не является нулевым, требуя, чтобы bucket не является нулевым, и его assignedVariantName не является нулевым Это требование делает его безопасным для использования bucket внутри let блок.

Другие вопросы по тегам