Можно ли скрыть переменные от закрытия лямбды?

Я пытаюсь создать в Kotlin безопасный конструктор в стиле groovy, как описано здесь. Проблема заключается в видимости лямбда-приемников во вложенных лямбдах. Вот простой пример.

html {
    head(id = "head1")
    body() {
        head(id = "head2")
    }
}

Получателем вложенной лямбды является тело, у которого нет метода «голова». Тем не менее этот код компилируется и печатается в это:

<html>
    <head id="head1"></head>
    <head id="head2"></head>
    <body></body>
</html>

Ожидается, но есть ли способ получить ошибку компиляции во внутренней головке?


person Alexey Pomelov    schedule 12.09.2016    source источник
comment
Если вы хотите, есть обходной путь: stackoverflow.com/a/37000303/2094298   -  person Ruckus T-Boom    schedule 12.09.2016


Ответы (2)


Начиная с Kotlin 1.0 это невозможно. Для этой функции существует открытый запрос.

person yole    schedule 12.09.2016

Это возможно, начиная с Kotlin 1.1, благодаря введение аннотации @DslMarker.

Вот пример того, как его можно использовать:

@DslMarker
annotation class MyHtmlDsl

@MyHtmlDsl
class HeadBuilder

@MyHtmlDsl
class BodyBuilder

@MyHtmlDsl
class HtmlBuilder {
    fun head(setup: HeadBuilder.() -> Unit) {}
    fun body(setup: BodyBuilder.() -> Unit) {}
}

fun html(setup: HtmlBuilder.() -> Unit) {}

fun main(args: Array<String>) {
    html {
        head {}
        body {
            head { } // fun head(...) can't be called in this context by implicit receiver
        }
    }
}

См. также документацию в объявлении, указанном выше.

person zsmb13    schedule 24.03.2018