Выбор ответа Senior Функции, расширения и scope-функции обновлено

Ловушка x?.let { } ?: run { }

Вопрос

Что выведет код?

fun saveOrNull(v: String): String? { println("save"); return null }

val value: String? = "data"
value?.let { saveOrNull(it) } ?: run { println("fallback") }

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: save, затем fallback. Идиому ?.let { } ?: run { } часто используют как if-else, но она работает иначе. value не null, поэтому let выполняется, и saveOrNull печатает save.

Варианты ответа

  1. save, затем fallbackправильный ответ
  2. Только save, а run пропущен
  3. Только fallback, let не вызван
  4. Ничего: оба блока пропущены

Разбор

Идиому ?.let { } ?: run { } часто используют как if-else, но она работает иначе. value не null, поэтому let выполняется, и saveOrNull печатает save. Но лямбда возвращает результат saveOrNull, то есть null, значит и весь let вернул null, и Elvis запускает run. Для ветвления по null надёжнее обычный if (value != null) ... else ....

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.