@DslMarker: Receiver-Leaks verhindern
Verwenden Sie @DslMarker-Annotationen, um Verschachtelungsregeln von DSLs zur Compile-Zeit durchzusetzen.
@DslMarker: Receiver-Leaks verhindern ist eine kostenlose Kotlin Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Kotlin Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Kotlin Academy-Kurs umfasst insgesamt 4 Lektionen.
Das Problem von Receiver-Leaks
In verschachtelten DSLs kann ein inneres Builder-Lambda versehentlich auf Member eines äußeren Receivers zugreifen. Beispielsweise könnten Sie innerhalb eines td { }-Blocks tr { } aus dem äußeren Tabellenbereich aufrufen – was fast nie beabsichtigt ist.
So sehen Receiver-Leaks aus
Ohne @DslMarker erlaubt der Compiler, Funktionen des äußeren Gültigkeitsbereichs aus jedem inneren Lambda aufzurufen, was zu einer verwirrenden und fehleranfälligen Verwendung der DSL führt:
// Without @DslMarker — this compiles but is wrong:
html {
body {
table {
tr { // outer scope leaks in
tr { } // calling tr inside tr — nonsensical
}
}
}
}@DslMarker einführen
@DslMarker ist eine Metaannotation, die Sie auf Ihre eigene Annotationsklasse anwenden. Jede mit Ihrer DSL-Annotation annotierte Builder-Klasse hat ihren impliziten Receiver in verschachtelten Lambdas ausgeblendet, die dieselbe DSL-Annotation verwenden.
@DslMarker
annotation class HtmlDsl
@HtmlDsl
class Table
@HtmlDsl
class TrSo funktioniert das Ausblenden impliziter Receiver
Wenn zwei verschachtelte Lambdas jeweils einen mit derselben @DslMarker-Annotation markierten Receiver haben, wird der äußere Receiver innerhalb des inneren Lambdas ausgeblendet. Ein direkter Zugriff darauf führt zu einem Kompilierungsfehler.
@DslMarker
annotation class HtmlDsl
@HtmlDsl class Html
@HtmlDsl class Body
@HtmlDsl class DivVollständiges Beispiel mit @DslMarker
Deklarieren Sie die Annotation, markieren Sie die Builder-Klassen, und verschachtelte Aufrufe von Methoden des äußeren Gültigkeitsbereichs werden zur Kompilierzeit erkannt:
@DslMarker
annotation class MyCfgDsl
@MyCfgDsl
class ServerBuilder {
var port: Int = 8080
fun database(block: DbBuilder.() -> Unit) { /*...*/ }
}
@MyCfgDsl
class DbBuilder {
var url: String = ""
// Cannot call ServerBuilder.port here — compiler error
}Die Einschränkung mit this@ umgehen
Wenn Sie wirklich auf einen äußeren Receiver aus einem inneren Lambda zugreifen müssen, verwenden Sie eine gelabelte this@OuterClass-Referenz. Das ist explizit und beabsichtigt, im Gegensatz zum versehentlichen Durchsickern.
fun ServerBuilder.database(block: DbBuilder.() -> Unit) {
val db = DbBuilder()
db.block()
val serverPort = this@ServerBuilder.port // explicit outer access
}@DslMarker bei mehreren DSLs
Verschiedene DSLs sollten unterschiedliche @DslMarker-Annotationen verwenden. Zwei nicht verwandte DSLs mit verschiedenen Markern beeinflussen sich nicht, selbst wenn sie verschachtelt sind.
@DslMarker annotation class HtmlDsl
@DslMarker annotation class GradleDsl
// HtmlDsl and GradleDsl receivers do not hide each otherAuf Builder und Receiver anwenden
Wenden Sie Ihre DSL-Annotation auf die Builder-Klasse selbst an. Die Annotation wird auf jeden Lambda-Parameter übertragen, dessen Receiver-Typ diese Klasse ist. Eine weitere Annotation einzelner Funktionen ist nicht nötig.
IDE-Unterstützung
IntelliJ IDEA und Android Studio markieren den Zugriff auf den äußeren Receiver sofort als Fehler, wenn @DslMarker verwendet wird. Dies gibt beim Erstellen oder Verwenden Ihrer DSL Echtzeitfeedback.
Für Sicherheit entwerfen
Ein gutes DSL-Design kombiniert jede Builder-Klasse mit @DslMarker. Der geringe Aufwand einer Annotation verbessert die Ergonomie der DSL erheblich und verhindert ganze Fehlerkategorien für DSL-Nutzende.
Verwendung in der Standardbibliothek
Kotlin verwendet sein eigenes @DslMarker in kotlinx.html, der Ktor-Routing-DSL, Gradle-Kotlin-Skripten und den buildMap/buildList-Buildern. Es ist ein grundlegendes Werkzeug in jedem ernst zu nehmenden DSL-Toolkit.
Kurzer Test
Was verhindert @DslMarker?
Zusammenfassung: @DslMarker
Wichtigste Erkenntnisse:
- Ohne
@DslMarkersickern äußere Receiver in innere DSL-Lambdas durch - Definieren Sie eine mit einer Metaannotation versehene Annotationsklasse und wenden Sie sie auf alle Builder-Klassen Ihrer DSL an
- Verschachtelte Lambdas mit demselben Marker können nicht versehentlich Member des äußeren Gültigkeitsbereichs aufrufen
- Verwenden Sie
this@OuterClass, wenn Sie tatsächlich auf den äußeren Gültigkeitsbereich zugreifen müssen
Lerne Kotlin mit einem KI-Tutor — kostenlos
Schreibe und führe echten Code in deinem Browser aus, bekomme sofortige Hilfe von einem 24/7 KI-Tutor und setze dein Lernen im Web oder in der App fort.
- Kurse
- 51
- Lektionen
- 203
Häufig gestellte Fragen
Ist die Lektion „@DslMarker: Receiver-Leaks verhindern“ kostenlos?
Ja — der vollständige Text von „@DslMarker: Receiver-Leaks verhindern“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Kotlin Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Kotlin Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „@DslMarker: Receiver-Leaks verhindern“?
Verwenden Sie @DslMarker-Annotationen, um Verschachtelungsregeln von DSLs zur Compile-Zeit durchzusetzen. Du übst Kotlin Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Kotlin Academy zu starten?
Keine Vorkenntnisse erforderlich. Kotlin Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.
Wie lange dauert die Lektion „@DslMarker: Receiver-Leaks verhindern“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Kotlin Academy-Lektion Code schreiben und ausführen?
Ja. Jede Kotlin Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Lambda mit Receiver: Grundlage für DSLs
- @DslMarker: Receiver-Leaks verhindern
- Eine typsichere HTML-/Config-DSL erstellen
- DSLs testen und weiterentwickeln, ohne Nutzer zu beeinträchtigen