Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗ktSpBdMk 28 of 299 menu
◀ ▶

Метка области в Kotlin

Во вложенном построителе внутренний блок иногда случайно вызывает метод внешнего получателя. Такой вызов компилируется, но ломает читаемость и путает уровни DSL.

Аннотация @DslMarker помечает семейство типов-построителей. Ее вешают на свою аннотацию, а ту - на классы получателей. Компилятор запрещает неявный доступ к внешнему this из вложенного блока с той же меткой:

@DslMarker annotation class UiMarker @UiMarker class Screen { val items = mutableListOf<String>() fun header(text: String) { items.add("h:$text") } fun group(block: Group.() -> Unit) { Group(this).block() } @UiMarker class Group(private val screen: Screen) { fun line(text: String) { screen.items.add("p:$text") } } }

Если внутри group попытаться вызвать header внешнего экрана, компилятор сообщит об ошибке: вложенный получатель не видит методы родительского уровня с общей меткой. Заголовок нужно задавать во внешнем блоке, а строки - во внутреннем:

fun buildScreen(block: Screen.() -> Unit): List<String> { val screen = Screen() screen.block() return screen.items } fun main() { val menu = buildScreen { header("home") group { line("news") line("blog") } } println(menu) }

Явный доступ через имя внешнего объекта метка не отменяет, но в DSL его обычно избегают. Разделение уровней делает структуру блоков предсказуемой для читателя.

Пометьте аннотацию @DslMarker и повесьте ее на внешний Deck и внутренний Slide. Заголовок колоды задайте снаружи, пункты - внутри slide.

Соберите две группы с разным числом строк и выведите итоговый список меток. Проверьте, что внутренний блок не вызывает методы Deck напрямую.

← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить