Что такое apply в Kotlin
Что проверяют
Знаете ли вы scope-функции как систему, а не одну apply в отрыве от остальных. Почти всегда следом спрашивают, чем apply отличается от also, let, run и with и когда какую брать.
Как отвечать
Начните с сигнатуры, она объясняет всё поведение: inline fun <T> T.apply(block: T.() -> Unit): T.
Внутри блока объект доступен как this (лямбда с получателем), поэтому к свойствам обращаются без имени. Возвращается сам объект, а не результат блока. Функция inline, так что лишнего объекта для лямбды не создаётся.
Отсюда назначение: настройка объекта сразу после создания. На Android типичные места такие:
Intent:Intent(context, DetailsActivity::class.java).apply { putExtra(KEY_ID, id) };- аргументы фрагмента:
DetailsFragment().apply { arguments = bundleOf(KEY_ID to id) }; - View из кода:
TextView(context).apply { text = title; textSize = 16f }; - билдеры:
NotificationCompat.Builder,Paintи другие объекты, которые удобно донастроить по месту.
Остальные функции проще запомнить по двум вопросам: как объект виден внутри и что возвращается.
also:it, возвращает объект, для побочных действий вроде логирования;let:it, возвращает результат блока, часто в паре с?.для nullable;run:this, возвращает результат блока;with: то же, чтоrun, но это не расширение, объект передаётся аргументом.
Где спотыкаются
Путают возвращаемое значение: пишут val len = str.apply { length } и получают строку, а не число. Для результата нужен run или let.
Не замечают затенение. Если у объекта и у окружающего класса есть свойство с одним именем, внутри apply выиграет свойство объекта, и name = name молча присвоит поле самому себе. Помогает явный this@MainActivity.name или переход на also.
Вкладывают apply в apply и в let. На третьем уровне уже непонятно, какой this имеется в виду, и код читается хуже, чем без scope-функций.