Kotlin Academy · Aula

@DslMarker: impedindo o vazamento de receptores

Use anotações @DslMarker para impor regras de aninhamento de DSL em tempo de compilação.

Aula 2 de 413 etapas

@DslMarker: impedindo o vazamento de receptores é uma aula grátis de Kotlin Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Kotlin Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Kotlin Academy inclui 4 aulas no total.

O problema do vazamento de receptores

Em DSLs aninhadas, uma lambda construtora interna pode acessar acidentalmente membros de um receptor externo. Por exemplo, dentro de um bloco td { }, você poderia chamar tr { } do escopo da tabela externa — o que quase nunca é intencional.

Como é o vazamento

Sem @DslMarker, o compilador permite chamar funções do escopo externo a partir de qualquer lambda interna, o que leva a um uso confuso e sujeito a erros da DSL:

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

Introduzindo @DslMarker

@DslMarker é uma meta-anotação que você aplica à sua própria classe de anotação. Qualquer classe construtora anotada com a anotação da sua DSL terá seu receptor implícito oculto em lambdas aninhadas que usam a mesma anotação da DSL.

@DslMarker
annotation class HtmlDsl

@HtmlDsl
class Table

@HtmlDsl
class Tr

Como funciona a ocultação do receptor implícito

Quando duas lambdas aninhadas têm receptores marcados com a mesma anotação @DslMarker, o receptor externo fica oculto dentro da lambda interna. Acessá-lo diretamente causa um erro de compilação.

@DslMarker
annotation class HtmlDsl

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

Exemplo completo com @DslMarker

Declare a anotação, marque as classes construtoras e, em seguida, as chamadas aninhadas a métodos do escopo externo serão detectadas em tempo de compilação:

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

Escapando da restrição com this@

Se você realmente precisar acessar um receptor externo a partir de uma lambda interna, use uma referência rotulada this@OuterClass. Isso é explícito e intencional, ao contrário do vazamento acidental.

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

@DslMarker com várias DSLs

DSLs diferentes devem usar anotações @DslMarker diferentes. Duas DSLs não relacionadas, com marcadores diferentes, não interferem uma na outra mesmo quando estão aninhadas.

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

Aplicando a construtoras e receptores

Aplique a anotação da sua DSL à própria classe construtora. A anotação se propaga para qualquer parâmetro de lambda cujo tipo de receptor seja essa classe. Não é necessária nenhuma anotação adicional em funções individuais.

Suporte da IDE

IntelliJ IDEA e Android Studio destacam imediatamente como erro o acesso ao receptor externo quando @DslMarker é usado. Isso fornece feedback em tempo real ao criar ou utilizar sua DSL.

Projetando para a segurança

Um bom projeto de DSL associa cada classe construtora a @DslMarker. É um pequeno custo de anotação que melhora significativamente a ergonomia da DSL e evita categorias inteiras de erros para quem a utiliza.

Uso na biblioteca padrão

O próprio @DslMarker do Kotlin é usado em kotlinx.html, na DSL de roteamento do Ktor, no script Kotlin do Gradle e nas construtoras buildMap/buildList. Ele é uma ferramenta fundamental em qualquer conjunto sério de ferramentas para DSLs.

Verificação rápida

O que @DslMarker impede?

Recapitulação: @DslMarker

Principais conclusões:

  • Sem @DslMarker, receptores externos vazam para lambdas internas da DSL
  • Defina uma classe de anotação com meta-anotação e aplique-a a todas as classes construtoras da sua DSL
  • Lambdas aninhadas com o mesmo marcador não podem chamar acidentalmente membros do escopo externo
  • Use this@OuterClass quando realmente precisar acessar o escopo externo
Grátis para começar

Aprenda Kotlin com um tutor de IA — grátis

Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.

Cursos
51
Aulas
203

Perguntas Frequentes

A aula “@DslMarker: impedindo o vazamento de receptores” é grátis?

Sim — o texto completo de “@DslMarker: impedindo o vazamento de receptores” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Kotlin Academy, atualize para CoddyKit PRO. O curso de Kotlin Academy inclui 4 aulas no total.

O que vou aprender em “@DslMarker: impedindo o vazamento de receptores”?

Use anotações @DslMarker para impor regras de aninhamento de DSL em tempo de compilação. Você pratica Kotlin Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Kotlin Academy?

Nenhuma experiência prévia é necessária. Kotlin Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.

Quanto tempo leva a aula “@DslMarker: impedindo o vazamento de receptores”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Kotlin Academy?

Sim. Cada aula de Kotlin Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Lambda com receptor: a base da DSL
  2. @DslMarker: impedindo o vazamento de receptores
  3. Criando uma DSL de HTML/configuração segura quanto a tipos
  4. Testando e evoluindo DSLs sem interromper os usuários
← Voltar para Kotlin Academy