@DslMarker: evitar fugas del receptor
Use anotaciones @DslMarker para aplicar las reglas de anidamiento de DSL en tiempo de compilación.
@DslMarker: evitar fugas del receptor es una lección gratuita de Kotlin Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Kotlin Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Kotlin Academy incluye 4 lecciones en total.
El problema de la fuga del receptor
En las DSL anidadas, una lambda builder interna puede acceder accidentalmente a miembros de un receptor externo. Por ejemplo, dentro de un bloque td { } podría llamar a tr { } desde el ámbito externo de la tabla, algo que casi nunca es intencionado.
Cómo se ve la fuga
Sin @DslMarker, el compilador permite llamar a funciones del ámbito externo desde cualquier lambda interna, lo que da lugar a un uso confuso y propenso a errores de la DSL:
// Without @DslMarker — this compiles but is wrong:
html {
body {
table {
tr { // outer scope leaks in
tr { } // calling tr inside tr — nonsensical
}
}
}
}Introducción de @DslMarker
@DslMarker es una metaanotación que se aplica a su propia clase de anotación. Cualquier clase builder anotada con la anotación de su DSL tendrá su receptor implícito oculto en las lambdas anidadas que utilicen esa misma anotación de DSL.
@DslMarker
annotation class HtmlDsl
@HtmlDsl
class Table
@HtmlDsl
class TrCómo funciona el ocultamiento del receptor implícito
Cuando dos lambdas anidadas tienen un receptor marcado con la misma anotación @DslMarker, el receptor externo se oculta dentro de la lambda interna. Acceder a él directamente provoca un error de compilación.
@DslMarker
annotation class HtmlDsl
@HtmlDsl class Html
@HtmlDsl class Body
@HtmlDsl class DivEjemplo completo con @DslMarker
Declare la anotación, marque las clases builder y las llamadas anidadas a métodos del ámbito externo se detectarán en tiempo de compilación:
@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
}Cómo escapar de la restricción con this@
Si realmente necesita acceder a un receptor externo desde una lambda interna, use una referencia etiquetada this@OuterClass. De este modo, el acceso es explícito e intencionado, a diferencia de una fuga accidental.
fun ServerBuilder.database(block: DbBuilder.() -> Unit) {
val db = DbBuilder()
db.block()
val serverPort = this@ServerBuilder.port // explicit outer access
}@DslMarker con varias DSL
Las distintas DSL deben usar anotaciones @DslMarker diferentes. Dos DSL no relacionadas con marcadores distintos no interfieren entre sí, incluso cuando están anidadas.
@DslMarker annotation class HtmlDsl
@DslMarker annotation class GradleDsl
// HtmlDsl and GradleDsl receivers do not hide each otherAplicación a builders y receptores
Aplique la anotación de su DSL directamente a la clase builder. La anotación se propaga a cualquier parámetro lambda cuyo tipo de receptor sea esa clase. No es necesario anotar individualmente más funciones.
Compatibilidad con el IDE
IntelliJ IDEA y Android Studio resaltan inmediatamente como error el acceso al receptor externo cuando se usa @DslMarker. Esto proporciona información en tiempo real al crear o utilizar la DSL.
Diseño orientado a la seguridad
Un buen diseño de DSL asocia cada clase builder con @DslMarker. Es un pequeño coste de anotación que mejora notablemente la ergonomía de la DSL y evita categorías enteras de errores para quienes la utilizan.
Uso en la biblioteca estándar
La propia @DslMarker de Kotlin se usa en kotlinx.html, la DSL de enrutamiento de Ktor, los scripts de Gradle Kotlin y los builders buildMap/buildList. Es una herramienta fundamental en cualquier conjunto de herramientas DSL serio.
Comprobación rápida
¿Qué evita @DslMarker?
Resumen: @DslMarker
Conclusiones clave:
- Sin
@DslMarker, los receptores externos se filtran en las lambdas internas de la DSL - Defina una clase de anotación con metaanotación y aplíquela a todas las clases builder de su DSL
- Las lambdas anidadas con el mismo marcador no pueden llamar accidentalmente a miembros del ámbito externo
- Use
this@OuterClasscuando realmente necesite acceder al ámbito externo
Aprende Kotlin con un tutor de IA — gratis
Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.
- Cursos
- 51
- Lecciones
- 203
Preguntas frecuentes
¿La lección «@DslMarker: evitar fugas del receptor» es gratis?
Sí — el texto completo de «@DslMarker: evitar fugas del receptor» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Kotlin Academy, actualiza a CoddyKit PRO. El curso de Kotlin Academy incluye 4 lecciones en total.
¿Qué aprenderé en «@DslMarker: evitar fugas del receptor»?
Use anotaciones @DslMarker para aplicar las reglas de anidamiento de DSL en tiempo de compilación. Practicas Kotlin Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Kotlin Academy?
No se requiere experiencia previa. Kotlin Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.
¿Cuánto tiempo toma la lección «@DslMarker: evitar fugas del receptor»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Kotlin Academy?
Sí. Cada lección de Kotlin Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Lambda con receptor: base de los DSL
- @DslMarker: evitar fugas del receptor
- Crear un DSL de HTML/configuración seguro respecto a tipos
- Probar y evolucionar DSL sin perjudicar a los usuarios