レシーバー付きLambda:DSLの基盤
レシーバー付き関数型と、それによってDSL構文が可能になる仕組みを理解します。
「レシーバー付きLambda:DSLの基盤」はCoddyKit上の無料Kotlin Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これは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 が何を指すかを把握できます。
クイックチェック
StringBuilder.() -> Unit 型のレシーバー付きラムダ内で、this は何を参照しますか。
まとめ: レシーバー付きラムダ
重要なポイント:
- レシーバー付きラムダは、ラムダ本体内で暗黙の
thisを提供します ReceiverType.() -> ReturnTypeと宣言します- すべての Kotlin DSL の基盤です
- 標準ライブラリでは
apply、with、run、buildStringなどで使用されています
よくある質問
「レシーバー付きLambda:DSLの基盤」レッスンは無料ですか?
はい。「レシーバー付きLambda:DSLの基盤」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Kotlin Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Kotlin Academyコースには全4レッスンが含まれています。
「レシーバー付きLambda:DSLの基盤」で何を学びますか?
レシーバー付き関数型と、それによってDSL構文が可能になる仕組みを理解します。 ブラウザで直接実行するハンズオンコードでKotlin Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Kotlin Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのKotlin Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「レシーバー付きLambda:DSLの基盤」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このKotlin Academyレッスンでコードを書いて実行できますか?
はい。すべてのKotlin Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- レシーバー付きLambda:DSLの基盤
- @DslMarker:レシーバーの漏洩を防ぐ
- 型安全なHTML/Config DSLの構築
- ユーザーを壊さずにDSLをテスト・進化させる