0Pricing
Kotlin Academy · Lezione

@DslMarker: impedire la fuoriuscita del receiver

Utilizzi le annotazioni @DslMarker per imporre le regole di annidamento delle DSL in fase di compilazione.

@DslMarker: impedire la fuoriuscita del receiver è una lezione Kotlin Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Kotlin Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Kotlin Academy include 4 lezioni in totale.

Il problema della fuoriuscita del receiver

Nelle DSL annidate, una lambda builder interna può accedere accidentalmente ai membri di un receiver esterno. Per esempio, all'interno di un blocco td { } si potrebbe chiamare tr { } dallo scope della tabella esterna, cosa quasi mai intenzionale.

Come si manifesta la fuoriuscita

Senza @DslMarker, il compilatore consente di chiamare le funzioni dello scope esterno da qualsiasi lambda interna, causando un uso della DSL confuso e soggetto a errori:

// Without @DslMarker — this compiles but is wrong:
html {
    body {
        table {
            tr {                // outer scope leaks in
                tr {  }         // calling tr inside tr — nonsensical
            }
        }
    }
}

Introduzione a @DslMarker

@DslMarker è una meta-annotazione che si applica a una propria classe di annotazione. Qualsiasi classe builder annotata con l'annotazione della DSL avrà il proprio receiver implicito nascosto nelle lambda annidate che usano la stessa annotazione della DSL.

@DslMarker
annotation class HtmlDsl

@HtmlDsl
class Table

@HtmlDsl
class Tr

Come funziona l'occultamento del receiver implicito

Quando due lambda annidate hanno entrambe un receiver contrassegnato con la stessa annotazione @DslMarker, il receiver esterno viene nascosto all'interno della lambda interna. L'accesso diretto provoca un errore in fase di compilazione.

@DslMarker
annotation class HtmlDsl

@HtmlDsl class Html
@HtmlDsl class Body
@HtmlDsl class Div

Esempio completo con @DslMarker

Dichiari l'annotazione, contrassegni le classi builder e le chiamate annidate ai metodi dello scope esterno vengono rilevate in fase di compilazione:

@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
}

Superare il vincolo con this@

Se è davvero necessario accedere a un receiver esterno da una lambda interna, si può usare un riferimento this@OuterClass con label. In questo modo l'accesso è esplicito e intenzionale, a differenza della fuoriuscita accidentale.

fun ServerBuilder.database(block: DbBuilder.() -> Unit) {
    val db = DbBuilder()
    db.block()
    val serverPort = this@ServerBuilder.port  // explicit outer access
}

@DslMarker con più DSL

DSL diverse dovrebbero usare annotazioni @DslMarker diverse. Due DSL non correlate con marker differenti non interferiscono tra loro nemmeno quando sono annidate.

@DslMarker annotation class HtmlDsl
@DslMarker annotation class GradleDsl
// HtmlDsl and GradleDsl receivers do not hide each other

Applicarlo a builder e receiver

Applichi l'annotazione della DSL direttamente alla classe builder. L'annotazione si propaga a qualsiasi parametro lambda il cui tipo receiver sia quella classe. Non è necessaria alcuna ulteriore annotazione delle singole funzioni.

Supporto dell'IDE

IntelliJ IDEA e Android Studio evidenziano immediatamente come errore l'accesso al receiver esterno quando viene usato @DslMarker. Questo fornisce un feedback in tempo reale durante la creazione o l'utilizzo della DSL.

Progettare per la sicurezza

Una buona progettazione delle DSL associa ogni classe builder a @DslMarker. È un piccolo sovraccarico dovuto all'annotazione, ma migliora notevolmente l'ergonomia della DSL e previene intere categorie di bug per chi la usa.

Utilizzo nella libreria standard

Il @DslMarker di Kotlin viene usato in kotlinx.html, nella DSL di routing di Ktor, negli script Gradle Kotlin e nei builder buildMap/buildList. È uno strumento fondamentale in qualsiasi toolkit serio per DSL.

Verifica rapida

Che cosa impedisce @DslMarker?

Riepilogo: @DslMarker

Punti chiave:

  • Senza @DslMarker, i receiver esterni fuoriescono nelle lambda interne della DSL
  • Definisca una classe di annotazione con meta-annotazione e la applichi a tutte le classi builder della DSL
  • Le lambda annidate con lo stesso marker non possono chiamare accidentalmente i membri dello scope esterno
  • Usi this@OuterClass quando è davvero necessario accedere allo scope esterno

Domande Frequenti

La lezione «@DslMarker: impedire la fuoriuscita del receiver» è gratuita?

Sì — il testo completo di «@DslMarker: impedire la fuoriuscita del receiver» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Kotlin Academy, passa a CoddyKit PRO. Il corso Kotlin Academy include 4 lezioni in totale.

Cosa imparerò in «@DslMarker: impedire la fuoriuscita del receiver»?

Utilizzi le annotazioni @DslMarker per imporre le regole di annidamento delle DSL in fase di compilazione. Eserciti Kotlin Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Kotlin Academy?

Non è richiesta alcuna esperienza precedente. Kotlin Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «@DslMarker: impedire la fuoriuscita del receiver»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Kotlin Academy?

Sì. Ogni lezione Kotlin Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Lambda con receiver: la base delle DSL
  2. @DslMarker: impedire la fuoriuscita del receiver
  3. Costruire una DSL HTML/Config type-safe
  4. Testare ed evolvere le DSL senza interrompere gli utenti
← Torna a Kotlin Academy