是否可以从 lambda 的闭包中隐藏变量?
Is it possible to hide variables from lambda's closure?
我正在尝试在 Kotlin 中创建一个类型安全的 groovy 风格的构建器,就像它所描述的那样 here。
问题是嵌套 lambda 中 lambda 接收器的可见性。
这是一个简单的例子。
html {
head(id = "head1")
body() {
head(id = "head2")
}
}
嵌套 lambda 的接收者是没有 'head' 方法的 Body。尽管如此,这段代码编译并打印成这样:
<html>
<head id="head1"></head>
<head id="head2"></head>
<body></body>
</html>
这是预料之中的,但是有什么方法可以让内头出现编译错误吗?
从 Kotlin 1.0 开始,这是不可能的。此功能有一个 open feature request。
由于 introduction of the @DslMarker
annotation.
,自 Kotlin 1.1 以来这是可能的
这是一个如何使用它的例子:
@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
}
}
}
另请参阅上面链接的公告中的文档。
我正在尝试在 Kotlin 中创建一个类型安全的 groovy 风格的构建器,就像它所描述的那样 here。 问题是嵌套 lambda 中 lambda 接收器的可见性。 这是一个简单的例子。
html {
head(id = "head1")
body() {
head(id = "head2")
}
}
嵌套 lambda 的接收者是没有 'head' 方法的 Body。尽管如此,这段代码编译并打印成这样:
<html>
<head id="head1"></head>
<head id="head2"></head>
<body></body>
</html>
这是预料之中的,但是有什么方法可以让内头出现编译错误吗?
从 Kotlin 1.0 开始,这是不可能的。此功能有一个 open feature request。
由于 introduction of the @DslMarker
annotation.
这是一个如何使用它的例子:
@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
}
}
}
另请参阅上面链接的公告中的文档。