С какими scope функциями работал

Ответ

В Android работал с различными scope-функциями Kotlin, такими как let, run, with, apply и also.

  • let – для выполнения кода с объектом, возвращает результат лямбды.
    user?.let { println(it.name) }
  • run – как let, но с доступом к свойствам через this.
    val length = "text".run { length }
  • with – аналогично run, но не extension-функция.
    with(user) { println(name) }
  • apply – возвращает сам объект (this), удобен для инициализации.
    val user = User().apply { name = "Alex" }
  • also – как apply, но принимает объект как it.
    user.also { println("User: ${it.name}") }

Выбор зависит от контекста: let для null-проверок, apply/also для модификации, run/with для вычислений.

Ответ 18+ 🔞

Давай разберем эту тему, а то у некоторых от этих let и apply глаза на лоб лезут, как будто они впервые про this и it слышат. Всё проще, чем кажется, если не загоняться.

Смотри, в Kotlin есть такие штуки — scope-функции. По сути, это просто способы временно поиграть с объектом в своей песочнице. Их пять штук: let, run, with, apply и also. Выбор зависит от того, что ты хочешь сделать и что в итоге получить. Главное — не перепутать, а то получится пиздопроебибна вместо кода.

Вот краткая шпаргалка, чтобы не бздеть каждый раз:

  • let — Классика для работы с nullable. Объект внутри лямбды — это it. Возвращает ты не сам объект, а результат последней строчки в лямбде. Идеально для цепочек проверок или преобразований.

    user?.let { println(it.name) } // Выведи имя, если user не null

    Типа: «Эй, объект, если ты есть (?), давай с тобой что-то сделаем и забудем».

  • run — Почти как let, но объект внутри — это уже this. Можно обращаться к его свойствам напрямую, без it.. Возвращает тоже результат лямбды. Часто используют для вычисления какого-то значения на основе объекта.

    val length = "text".run { length } // this.length, но this писать не надо

    Удивление пиздец, но иногда это читается лучше, чем let.

  • with — Старший, но не самый умный брат run. Не extension-функция, а принимает объект первым аргументом. Внутри лямбды объект — это this. Возвращает результат лямбды. Удобно, когда нужно много раз обращаться к свойствам одного объекта, чтобы не писать его имя каждый раз.

    with(user) { println(name) } // Всё равно что user.name, но короче
  • apply — А вот это мой фаворит для настройки объектов. Внутри лямбды объект — это this, а возвращает он сам этот объект (this). Идеально, когда ты создал экземпляр и сразу хочешь ему накрутить свойств.

    val user = User().apply { name = "Alex" } // Настроил и вернул того же самого user

    Красота! Создал, настроил — и поехал дальше. Волнение ебать от такой простоты.

  • also — Близнец apply, но с другим подходом. Объект внутри лямбды — это it, а возвращает он опять же сам объект. Идеален для сайд-эффектов: логирования, отладки, каких-то промежуточных действий, когда тебе нужно и объект сохранить, и что-то с ним сделать.

    user.also { println("User: ${it.name}") } // Посмотрел, что внутри, и передал user дальше

Короче, чувак, выбор простой:

  1. Нужно проверить на null и что-то сделать? — let.
  2. Нужно создать и сразу настроить объект? — apply.
  3. Нужно что-то посчитать на основе объекта и получить результат? — run или with.
  4. Нужно объект и модифицировать, и вернуть, но при этом залогировать что-то? — also.

Если начнёшь их все в одну кучу мешать бездумно, получится манда с ушами, которую потом сам не разберёшь. Пользуйся с умом, и код станет чище, а жизнь — проще.