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

При использовании функции .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 а assignVariantName – это переменная с нулевым значением.

 val bucket: T? = ... 

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

    (допустимый пример случая)

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

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