Можно ли не писать return в лямбда выражениях Kotlin
Что проверяют
Знаете ли вы, что лямбда возвращает значение последнего выражения, и понимаете ли, куда ведёт return внутри неё. Следом почти всегда спрашивают про return в forEach и про метки вида return@forEach.
Как отвечать
Да, и обычно так и пишут. Результатом лямбды становится значение последнего выражения в её теле, сколько бы строк ни было до него. Если ожидаемый тип Unit, последнее выражение просто игнорируется.
Сам return в лямбде ведёт себя по-разному:
- обычная лямбда:
returnбез метки запрещён, компилятор выдаст ошибку. С меткойreturn@map valueзначение вернётся из этой лямбды; - лямбда в
inline-функции (forEach,let,run,apply): голыйreturnделает нелокальный выход, то есть завершает всю внешнюю функцию, а не итерацию; crossinline: запрещает нелокальный выход, когда лямбда вызывается из другого контекста выполнения;- анонимная функция
fun(x: Int): Int { return x * 2 }: здесьreturnотносится к ней самой, как в обычной функции.
Пример из Android, который хорошо заходит: setOnLongClickListener { showMenu(); true }. Слушатель ждёт Boolean, поэтому последним выражением должно стоять true или false, а return писать не нужно. В setOnClickListener тип Unit, и возвращать ничего не требуется.
Для пропуска элемента в forEach используйте return@forEach, это аналог continue. Аналога break нет, поэтому для досрочного выхода лучше обычный for или firstOrNull и any, которые сами останавливаются на первом совпадении.
Где спотыкаются
Пишут return в forEach, ожидая пропуск элемента. Завершается вся функция, и код после цикла не выполняется. Ошибка тихая, компилятор её пропускает.
Забывают true в конце setOnLongClickListener. Если последним стоит вызов, возвращающий Unit, будет ошибка несоответствия типов, а попытка исправить её через return true даёт вторую ошибку: слушатель не inline, и голый return в его лямбде запрещён.
Смешивают типы веток. В лямбде без явного типа, где if возвращает Int, а else строку, выводится общий супертип вроде Any, и ошибка вылезает далеко от места, где её сделали.