Создание API в стиле DSL
Используйте инфиксную запись для ясности
«Создание API в стиле DSL» — бесплатный урок Kotlin Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Kotlin Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Kotlin Academy содержит 4 уроков всего.
Инфиксные функции для ясности
Инфиксные функции — один из строительных блоков DSL Kotlin, то есть предметно-ориентированных языков. Они позволяют читать вызовы API как естественные фразы.
infix fun String.eq(value: String) = this == value
fun main() {
println("on" eq "on")
}Идея выразительного построителя
Сочетание инфиксных функций с небольшими типами позволяет декларативно выражать намерение.
class Query(val field: String) {
infix fun equals(value: String) = "$field = '$value'"
}
fun main() {
val q = Query("name") equals "Sam"
println(q)
}Конфигурация на основе пар
Инфиксная функция to помогает создавать легко читаемые карты конфигурации.
fun configure(vararg opts: Pair<String, Any>) = opts.toMap()
fun main() {
val cfg = configure("debug" to true, "level" to 3)
println(cfg)
}DSL диапазонов
Благодаря инфиксным функциям построители диапазонов читаются почти как английские фразы.
fun main() {
val r = 1 until 10 step 2
println(r.toList())
}Объединение условий
С помощью инфиксных функций можно составлять выразительные фразы, похожие на логические условия.
data class Rule(val ok: Boolean) {
infix fun and(other: Rule) = Rule(ok && other.ok)
}
fun main() {
val result = Rule(true) and Rule(false)
println(result.ok)
}Лямбды с получателями
Настоящие DSL часто сочетают инфиксные функции с лямбдами, у которых есть получатели, позволяя блоку напрямую настраивать объект.
class Html {
val parts = mutableListOf<String>()
fun p(text: String) { parts.add("<p>$text</p>") }
}
fun html(block: Html.() -> Unit): Html {
val h = Html()
h.block()
return h
}
fun main() {
val page = html { p("Hi") }
println(page.parts)
}Как работают лямбды с получателем
Тип функции вроде Html.() -> Unit заставляет блок выполняться так, словно он находится внутри экземпляра Html, поэтому к его членам можно обращаться без префикса.
class Box { var value = 0 }
fun box(init: Box.() -> Unit): Box {
val b = Box()
b.init()
return b
}
fun main() {
val b = box { value = 42 }
println(b.value)
}apply как мини-DSL
Стандартная функция apply сама является DSL на основе лямбды с получателем для настройки объекта.
class Server {
var host = ""
var port = 0
}
fun main() {
val s = Server().apply {
host = "localhost"
port = 8080
}
println("${s.host}:${s.port}")
}Сохраняйте читаемость DSL
Хороший DSL сводит лишний шум к минимуму. Отдавайте предпочтение именам, благодаря которым место вызова читается как описание намерения.
data class Style(var bold: Boolean = false)
fun style(block: Style.() -> Unit) = Style().apply(block)
fun main() {
val s = style { bold = true }
println(s.bold)
}Инфиксная функция и лямбда
Сочетание инфиксных функций с лямбдами позволяет создавать выразительные построители.
class Table {
val rows = mutableListOf<String>()
infix fun row(text: String) { rows.add(text) }
}
fun table(block: Table.() -> Unit) = Table().apply(block)
fun main() {
val t = table {
row("A")
row("B")
}
println(t.rows)
}Когда стоит создавать DSL
DSL особенно полезны для повторяющейся структурированной конфигурации: пользовательских интерфейсов, построителей и тестов. Для разовой логики обычные функции проще.
fun main() {
val list = buildList {
add(1)
add(2)
}
println(list)
}Быстрая проверка
Проверьте, насколько хорошо Вы поняли API, похожие на DSL.
Итоги
Вы научились создавать API, похожие на DSL:
- Инфиксные функции позволяют читать вызовы как фразы.
- Лямбды с получателем (
Type.() -> Unit) позволяют блокам напрямую настраивать объекты. applyиbuildList— это DSL стандартной библиотеки.- Используйте DSL для структурированной повторяющейся конфигурации и сохраняйте их читаемость.
class C { var x = 0 }
fun c(b: C.() -> Unit) = C().apply(b)
fun main() {
println(c { x = 9 }.x)
}Часто задаваемые вопросы
Урок «Создание API в стиле DSL» бесплатный?
Да — полный текст урока «Создание API в стиле DSL» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Kotlin Academy, подпишись на CoddyKit PRO. Курс Kotlin Academy содержит 4 уроков всего.
Чему я научусь в уроке «Создание API в стиле DSL»?
Используйте инфиксную запись для ясности Ты практикуешь Kotlin Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Kotlin Academy?
Предыдущий опыт не требуется. Kotlin Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Создание API в стиле DSL»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Kotlin Academy?
Да. Каждый урок Kotlin Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Инфиксные функции
- Создание API в стиле DSL
- Функции tailrec
- Когда что использовать