DSL風APIの構築
明確さのためにinfixを使用します
「DSL風APIの構築」はCoddyKit上の無料Kotlin Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはKotlin Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Kotlin Academyコースには全4レッスンが含まれています。
明確さのためのインフィックス
インフィックス関数は、Kotlin のDSL(ドメイン固有言語)を構成する要素です。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)
}Pair ベースの設定
インフィックス関数 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)
}ミニ DSL としての apply
標準の 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 は、繰り返し行う構造化された設定(UI、ビルダー、テスト)で効果を発揮します。一度きりのロジックには、通常の関数のほうがシンプルです。
fun main() {
val list = buildList {
add(1)
add(2)
}
println(list)
}理解度チェック
DSL のような API についての理解度を確認しましょう。
まとめ
DSL のような APIの構築方法を学びました。
- インフィックス関数を使うと、呼び出しをフレーズのように読めます。
- レシーバー付きラムダ(
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)
}よくある質問
「DSL風APIの構築」レッスンは無料ですか?
はい。「DSL風APIの構築」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Kotlin Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Kotlin Academyコースには全4レッスンが含まれています。
「DSL風APIの構築」で何を学びますか?
明確さのためにinfixを使用します ブラウザで直接実行するハンズオンコードでKotlin Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Kotlin Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのKotlin Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「DSL風APIの構築」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このKotlin Academyレッスンでコードを書いて実行できますか?
はい。すべてのKotlin Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。