Является ли `a? .Let {}?: Run {}` идиоматическим в Kotlin? - PullRequest
0 голосов
/ 27 сентября 2018

Я увидел следующий комментарий в SO сообщении, и я заинтригован:

почему вы не используете if для нулевых проверок?a?.let{} ?: run{} подходит только в редких случаях, в противном случае это не идиоматично - voddan 15 мая 16 в 7:29 лучший способ обнулить проверку в kotlin?

Почемуэта конструкция «подходит только в редких случаях»?
Ведущий инженер Kotlin говорит:

run позволяет использовать несколько операторов справа от оператора elvis https://stackoverflow.com/a/51241983/6656019

хотя я признаю, что на самом деле не одобряю это как идиоматическое.Кажется, что оба этих поста принадлежат очень уважаемым авторам SO Kotlin.
В посте, вдохновлявшем оригинальный комментарий, упоминается, что часть выражения let важна, если a является изменчивым.В этом случае вам понадобится a?.let{} ?: run{} вместо if{} else {}.

Я нахожу, что мне нравится конструкция "let Elvis run".Должен ли я избегать этого в большинстве случаев?
Спасибо за понимание.

Ответы [ 2 ]

0 голосов
/ 12 марта 2019

Сравнивать foo?.let { bar(it) } ?: baz() с if (foo != null) bar(foo) else baz().

опасно. Допустим, у вас есть функция: fun computeElements(): List<Int>? = emptyList()

Рассмотрите этот код:

val maxElement = computeElements()?.let { it.max() } ?: return
println("Max element was $maxElement")

По сравнениюto:

val list: List<Int>? = computeElements()
val maxElement = if (list != null) list.max() else return
println("Max element was $maxElement")

Вы можете подумать, что это две эквивалентные формы.Однако, если вы запустите оба, вы увидите, что первый ничего не печатает на стандартный вывод!

Это потому, что it.max() возвращает null для пустого списка (потому что нет элемента max),что приводит к оценке правой части выражения Элвиса, и поэтому функция return s рано.

Короче говоря, ?.let { ... } ?: ... разрешает обе ветви "if-else" подлежит оценке, что опасно.Помимо того, что эта форма не читается (if-else понимается повсеместно, а let-run нет), могут возникать незначительные ошибки.

0 голосов
/ 27 сентября 2018

В этом случае вам понадобится? .Let {}?: Run {} вместо if {} else {}

Нет, вы можете пропустить часть выполненияиз run { statement } и использовать a?.let{} ?: statement.

Стоит ли мне избегать этого в большинстве случаев?

Вы должны использовать его, когда вам это нужно.Например, если вы хотите запустить несколько операторов в этом сценарии.Указывается, что это редкий сценарий.Часто вы увидите только один оператор справа от оператора elvis.
И, конечно, не используйте его, когда он вам не нужен.Сохраняйте код простым.

...