Что такое with {}

Ответ

with — это функция-расширение Kotlin, которая позволяет выполнить блок кода в контексте переданного объекта. Внутри блока this ссылается на объект, а результат — последнее выражение в блоке.

Пример:

val text = with(StringBuilder()) {
    append("Hello")
    append(", ")
    append("world!")
    toString() // результат
}
// text = "Hello, world!"

Особенности:

  • Не изменяет исходный объект (в отличие от apply).
  • Возвращает результат блока, а не объект.
  • Упрощает работу с объектами, требующими множественных операций.

Ответ 18+ 🔞

А, ну это же классика, ёпта! with — это как будто ты заходишь в гости к объекту и начинаешь там хозяйничать, но не навсегда, а только пока чай не допьешь.

Представь, что у тебя есть StringBuilder — этакая мартышлюшка, которая умеет склеивать текст. Без with ты бы писал так:

val builder = StringBuilder()
builder.append("Hello")
builder.append(", ")
builder.append("world!")
val text = builder.toString()

Скучно же, блядь! Один и тот же builder повторяется, как заезженная пластинка. Терпения ноль ебать.

А вот с with — красота, ядрёна вошь!

val text = with(StringBuilder()) {
    append("Hello") // Смотри-ка, а `this` — это уже наш StringBuilder!
    append(", ")
    append("world!")
    toString() // Вот это вот последнее выражение — оно и будет результатом всей этой движухи.
}
// text = "Hello, world!"

Что тут происходит, по пунктам:

  1. Заходим в контекст: with(StringBuilder()) — ты создаёшь нового StringBuilder и говоришь: "Чувак, я сейчас буду внутри тебя работать".
  2. this — это он: Внутри фигурных скобок this волшебным образом превращается в этот самый свежесозданный StringBuilder. Поэтому можно просто писать append(...), а не builder.append(...). Удобно, бля!
  3. Делаем что надо: Внутри блока ты делаешь с объектом всё, что душе угодно — вызываешь методы, меняешь свойства.
  4. Возвращаем НЕ объект, а ЧТО ХОТИМ: Вот тут главный фокус, чтобы не обосраться. Функция with возвращает не сам объект, а результат последней строчки в блоке.
    • В примере выше последняя строчка — toString(). Вот эта строка и станет значением переменной text.
    • Если бы последней строчкой было append("!"), то with вернула бы не строку, а сам StringBuilder (потому что append возвращает this). Это частая ошибка у новичков — они забывают последнюю строчку и потом охуевают, почему в text лежит не строка, а какой-то объект.

Чем не является with:

  • Это не apply. apply всегда возвращает сам объект (this). А with — что скажешь в последней строчке, то и вернёт. apply — это "настроить и отдать". with — это "поработать с ним и выдать какой-то итог".
  • Он не меняет объект магически. Если объект неизменяемый (immutable), то with его не изменит. Он просто даёт к нему удобный доступ.

Итог: Используй with, когда тебе нужно взять объект, сделать с ним кучу операций и получить КАКОЙ-ТО РЕЗУЛЬТАТ ЭТИХ ОПЕРАЦИЙ. Не сам объект, а именно результат. Например, преобразовать, вычислить что-то на его основе. Если тебе нужен просто настроенный объект — тебе в apply или also.

Понял? А то смотри, не перепутай, а то будет тебе не "Hello, world!", а хуй с горы.