Budowanie API podobnych do DSL
Używaj infix dla większej przejrzystości
Budowanie API podobnych do DSL to bezpłatna lekcja Kotlin Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Kotlin Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Kotlin Academy zawiera 4 lekcji w sumie.
Składnia infiksowa dla czytelności
Funkcje infiksowe są jednym z elementów składowych DSL-i Kotlina (języków dziedzinowych). Sprawiają, że wywołania API przypominają naturalne zwroty.
infix fun String.eq(value: String) = this == value
fun main() {
println("on" eq "on")
}Pomysł na płynny konstruktor
Połączenie składni infiksowej z małymi typami pozwala deklaratywnie wyrażać intencje.
class Query(val field: String) {
infix fun equals(value: String) = "$field = '$value'"
}
fun main() {
val q = Query("name") equals "Sam"
println(q)
}Konfiguracja oparta na parach
Infiksowa funkcja to umożliwia tworzenie czytelnych map konfiguracyjnych.
fun configure(vararg opts: Pair<String, Any>) = opts.toMap()
fun main() {
val cfg = configure("debug" to true, "level" to 3)
println(cfg)
}DSL zakresów
Dzięki składni infiksowej konstruktory zakresów przypominają język naturalny.
fun main() {
val r = 1 until 10 step 2
println(r.toList())
}Łączenie warunków
Za pomocą funkcji infiksowych można tworzyć czytelne wyrażenia przypominające zwroty logiczne.
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)
}Lambdy z receiverem
Prawdziwe DSL-e często łączą składnię infiksową z lambdami mającymi receiver, dzięki czemu blok może bezpośrednio konfigurować obiekt.
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)
}Wyjaśnienie lambd z receiverem
Typ funkcji taki jak Html.() -> Unit sprawia, że blok jest wykonywany tak, jakby znajdował się wewnątrz instancji Html, więc do elementów składowych można odwoływać się bez prefiksu.
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 jako mały DSL
Standardowa funkcja apply sama jest DSL-em opartym na lambdzie z receiverem, służącym do konfigurowania obiektu.
class Server {
var host = ""
var port = 0
}
fun main() {
val s = Server().apply {
host = "localhost"
port = 8080
}
println("${s.host}:${s.port}")
}Zachowuj czytelność DSL-i
Dobry DSL ogranicza zbędne elementy. Wybieraj nazwy, dzięki którym miejsce wywołania opisuje intencję.
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)
}Składnia infiksowa i lambda
Połączenie funkcji infiksowych z lambdami pozwala tworzyć ekspresywne konstruktory.
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)
}Kiedy budować DSL
DSL-e sprawdzają się przy powtarzalnej, strukturalnej konfiguracji (interfejsów użytkownika, konstruktorów i testów). W przypadku jednorazowej logiki zwykłe funkcje są prostsze.
fun main() {
val list = buildList {
add(1)
add(2)
}
println(list)
}Szybkie sprawdzenie
Sprawdź swoją wiedzę na temat interfejsów API przypominających DSL.
Podsumowanie
Opanowali Państwo tworzenie interfejsów API przypominających DSL:
- Funkcje infiksowe sprawiają, że wywołania przypominają naturalne zwroty.
- Lambdy z receiverem (
Type.() -> Unit) pozwalają blokom bezpośrednio konfigurować obiekty. applyibuildListto DSL-e biblioteki standardowej.- Używaj DSL-i do strukturalnej, powtarzalnej konfiguracji i dbaj o ich czytelność.
class C { var x = 0 }
fun c(b: C.() -> Unit) = C().apply(b)
fun main() {
println(c { x = 9 }.x)
}Często zadawane pytania
Czy lekcja „Budowanie API podobnych do DSL” jest bezpłatna?
Tak — pełny tekst „Budowanie API podobnych do DSL” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Kotlin Academy, przejdź na CoddyKit PRO. Kurs Kotlin Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Budowanie API podobnych do DSL”?
Używaj infix dla większej przejrzystości Ćwiczysz Kotlin Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Kotlin Academy?
Nie wymagamy żadnego doświadczenia. Kotlin Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „Budowanie API podobnych do DSL”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Kotlin Academy?
Tak. Każda lekcja Kotlin Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Funkcje infiksowe
- Budowanie API podobnych do DSL
- Funkcje tailrec
- Kiedy używać poszczególnych rozwiązań