【发布时间】:2025-12-17 04:55:01
【问题描述】:
我正在为 HTML 构建一个 Kotlin DSL,以满足我非常具体的要求(因此不使用 kotlinx.html)
DIV(classes = "div1") {
+"text1"
a(href = "#0") {
+"text2"
div(classes = "div2") {
+"text3"
href = "#1"
}
div(classes = "div3") {
+"text4"
href = "#2"
}
}
hr(classes = "hr1")
span(classes = "span1") {
+"text5"
}
}
在上面的示例中,我可以在a 的任何子元素中调用href,而不必执行this@a.href = ""。我如何限制范围,以便 this 在此示例中仅属于 DIV 类型,并在调用 href 时引发编译器错误,因为 DIV 没有 href 属性?
这是DIV 类的简化版本
https://github.com/persephone-unframework/dsl/blob/master/src/main/kotlin/io/persephone/dsl/element/DIV.kt
@DslMarker
annotation class DivMarker
@DivMarker
class DIV(
classes: String? = null,
....
init: (DIV.() -> Unit)? = null
) : Tag(
tagName = "div",
selfClosing = false
) {
fun a(
classes: String? = null,
....
init: (A.() -> Unit)? = null
) = A().let {
this.children.add(it)
....
init?.invoke(it)
it
}
....
}
同样,A 类也被标记: https://github.com/persephone-unframework/dsl/blob/master/src/main/kotlin/io/persephone/dsl/element/A.kt
@DslMarker
annotation class AMarker
@AMarker
class A(
href: String? = null,
...
init: (A.() -> Unit)? = null
) : Tag(
tagName = "a",
selfClosing = false
) {
fun div(
classes: String? = null,
init: (DIV.() -> Unit)? = null
) = DIV().let {
this.children.add(it)
....
init?.invoke(it)
it
}
....
}
知道为什么@DslMarker 注释不限制这种情况下的范围以及我该如何解决?
【问题讨论】: