我将使用实现DSL创建的文档中的官方示例.
从Kotlin 1.1开始,@DslMarker注释允许我们限制类中函数的范围,就像@HtmlTagMarker注释中的示例一样.当尝试编写错误的结构化代码时,这会给我们一个错误:
html {
body {
body { // this in an error, as it's a function call on the outside Html element
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,这并不能阻止嵌套最外层函数,这是DSL的入口点.例如,使用现在的示例,可以毫无问题地写下来:
html {
html {
}
}
Run Code Online (Sandbox Code Playgroud)
有没有办法让DSL在这方面更安全?
hot*_*key 10
也许这可以以更优雅的方式完成,但我可以建议在具有为接收器类型定义的匹配签名的函数上使用@Deprecated注释DeprecationLevel.ERROR,例如:
@Deprecated("Cannot be used in a html block.", level = DeprecationLevel.ERROR)
fun HtmlReceiver.html(action: HtmlReceiver.() -> Unit): Nothing = error("...")
Run Code Online (Sandbox Code Playgroud)
或者这可以是成员函数.顺便说一句,IDE完成的行为有点不同,具体取决于它是扩展还是成员.
这将使内部调用无效:
html {
html { // Error: Cannot be used in a html block.
}
}
Run Code Online (Sandbox Code Playgroud)
顶层函数仍然可以通过其FQN在DSL块内调用,例如com.example.html { },因此该技巧仅保护用户不会错误地调用顶级函数.
| 归档时间: |
|
| 查看次数: |
266 次 |
| 最近记录: |