0Pricing
Kotlin Academy · Урок

Лямбда с получателем: основа DSL

Разберитесь в типах функций с получателями и в том, как они обеспечивают синтаксис DSL.

«Лямбда с получателем: основа DSL» — бесплатный урок Kotlin Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Kotlin Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Kotlin Academy содержит 4 уроков всего.

Что такое лямбда с получателем

Лямбда с получателем — это литерал функции, тело которой имеет доступ к членам назначенного объекта-получателя без какого-либо квалификатора. Тип имеет вид: (ReceiverType) -> ReturnType, записываемый как ReceiverType.() -> ReturnType.

Сравнение синтаксиса

Обычная лямбда: { value: Int -> value + 1 }. Лямбда с получателем: StringBuilder.() -> Unit — внутри этой лямбды this обозначает экземпляр StringBuilder.

val addHello: StringBuilder.() -> Unit = {
    append("Hello")   // this = StringBuilder
    append(", World")
}

Использование with для применения лямбды с получателем

Функция стандартной библиотеки with принимает получатель и лямбду с получателем. Она вызывает лямбду, передавая заданный объект в качестве this:

val result = with(StringBuilder()) {
    append("Kotlin")
    append(" DSLs")
    toString()
}  // result = "Kotlin DSLs"

Объявление собственной функции-построителя

Вы можете писать функции, принимающие лямбды с получателями, чтобы создавать небольшие API для построения объектов:

class HtmlTag(val name: String) {
    val children = mutableListOf<HtmlTag>()
    fun render(): String = "<$name>${children.joinToString("") { it.render() }}</$name>"
}

fun div(block: HtmlTag.() -> Unit): HtmlTag {
    val tag = HtmlTag("div")
    tag.block()
    return tag
}

Вызов функции-построителя

Внутри лямбды this — это HtmlTag, поэтому его члены доступны напрямую:

val page = div {
    children += HtmlTag("p")
}

apply — это лямбда с получателем

Функция для работы с областью видимости apply — самый простой пример: она вызывает лямбду с получателем для this и возвращает this:

val list = mutableListOf<Int>().apply {
    add(1)
    add(2)
    add(3)
}   // list = [1, 2, 3]

Шаблон DSL

DSL строятся с помощью вложенных функций-построителей, каждая из которых принимает лямбду с получателем. Каждый уровень управляет собственным получателем, создавая естественную структуру с отступами, отражающую иерархию данных.

html {
    head { title("My Page") }
    body {
        div {
            p("Hello!")
        }
    }
}

Типы функций с получателем

Вы можете сохранять лямбды с получателями в переменных, используя тип функции T.() -> R:

val greet: String.() -> String = { "Hello, $this!" }
println("World".greet())  // "Hello, World!"

Функции-расширения и лямбды с получателем

Функции-расширения и лямбды с получателем используют один и тот же механизм: обе предоставляют неявный this. Разница в том, что функция-расширение объявляется во время компиляции, а лямбда с получателем является значением, которое можно передавать дальше.

Композиция лямбд с получателем

Несколько функций-построителей можно объединять, создавая сложные иерархические DSL. Главное, чтобы каждая функция-построитель задавала собственного получателя, сохраняя области видимости изолированными.

Вывод типов и лямбды с получателем

Kotlin выводит тип получателя из объявления параметра, поэтому вызывающему коду не нужно явно указывать тип лямбды. Компилятор знает, что означает this внутри блока.

Быстрая проверка

Что обозначает this внутри лямбды с получателем типа StringBuilder.() -> Unit?

Итоги: лямбда с получателем

Основные выводы:

  • Лямбда с получателем предоставляет неявный this внутри своего тела
  • Объявляется как ReceiverType.() -> ReturnType
  • Является основой всех DSL Kotlin
  • Стандартная библиотека использует её в apply, with, run, buildString и т. д.

Часто задаваемые вопросы

Урок «Лямбда с получателем: основа DSL» бесплатный?

Да — полный текст урока «Лямбда с получателем: основа DSL» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Kotlin Academy, подпишись на CoddyKit PRO. Курс Kotlin Academy содержит 4 уроков всего.

Чему я научусь в уроке «Лямбда с получателем: основа DSL»?

Разберитесь в типах функций с получателями и в том, как они обеспечивают синтаксис DSL. Ты практикуешь Kotlin Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Kotlin Academy?

Предыдущий опыт не требуется. Kotlin Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «Лямбда с получателем: основа DSL»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Kotlin Academy?

Да. Каждый урок Kotlin Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Лямбда с получателем: основа DSL
  2. @DslMarker: предотвращение утечки получателя
  3. Создание типобезопасного DSL для HTML/конфигурации
  4. Тестирование и развитие DSL без нарушения совместимости
← Назад к Kotlin Academy