调用接口中声明的接收函数
Invoke receiver function declared in interface
我正在尝试为个人项目创建一个易于使用的 html 生成器。我想我会使用扩展函数来生成一个 html 以编程方式使用这样的东西:
html {
head {
title("Site title")
}
body {
div {
// stuff in div
}
}
}
为此我声明了一个接口:
fun interface TagBlock {
operator fun Tag.invoke()
}
其中 Tag
将是指定特定标签的 class,例如 html
、body
、div
等:
class Tag(val name: String)
我现在尝试创建一个接受前面提到的接口和 returns 标签的函数:
fun html(block: TagBlock): Tag {
val html = Tag("html")
// invoke `block` with `html`
return html
}
我对如何调用提供的参数感到困惑 block
。以下均无效:
block(html) // Unresolved reference
block.invoke(html) // unresolved reference
html.block() // Unresolved reference: block
我哪里做错了?
您声明的 invoke()
运算符有 2 个接收者:
- 发送接收者
TagBlock
- 显式接收者
Tag
您需要在调用的上下文中提供调度接收器,它才能工作。您可以使用库函数 with()
:
fun html(block: TagBlock): Tag {
val html = Tag("html")
with(block) {
html.invoke()
}
return html
}
不过,这可能是也可能不是您正在寻找的使用体验。
Kotlin 中更惯用的方法是仅将函数类型作为输入:
fun html(block: Tag.() -> Unit): Tag {
val html = Tag("html")
html.block()
return html
}
我正在尝试为个人项目创建一个易于使用的 html 生成器。我想我会使用扩展函数来生成一个 html 以编程方式使用这样的东西:
html {
head {
title("Site title")
}
body {
div {
// stuff in div
}
}
}
为此我声明了一个接口:
fun interface TagBlock {
operator fun Tag.invoke()
}
其中 Tag
将是指定特定标签的 class,例如 html
、body
、div
等:
class Tag(val name: String)
我现在尝试创建一个接受前面提到的接口和 returns 标签的函数:
fun html(block: TagBlock): Tag {
val html = Tag("html")
// invoke `block` with `html`
return html
}
我对如何调用提供的参数感到困惑 block
。以下均无效:
block(html) // Unresolved reference
block.invoke(html) // unresolved reference
html.block() // Unresolved reference: block
我哪里做错了?
您声明的 invoke()
运算符有 2 个接收者:
- 发送接收者
TagBlock
- 显式接收者
Tag
您需要在调用的上下文中提供调度接收器,它才能工作。您可以使用库函数 with()
:
fun html(block: TagBlock): Tag {
val html = Tag("html")
with(block) {
html.invoke()
}
return html
}
不过,这可能是也可能不是您正在寻找的使用体验。
Kotlin 中更惯用的方法是仅将函数类型作为输入:
fun html(block: Tag.() -> Unit): Tag {
val html = Tag("html")
html.block()
return html
}