为什么 apply() 而不是函数调用
Why apply() instead of function invokation
下面的代码做同样的事情。函数 tr 和 td 以 函数字面量和接收者对象 作为输入,以添加 tr 或table.
内的 td 标签
class TABLE : Tag("table") {
fun tr(init: TR.() -> Unit) {
children += TR().apply(init)
}
}
class TR : Tag("tr") {
fun td(init: TD.() -> Unit) {
val td = TD()
td.init()
children += td
}
}
我的问题是为什么我需要使用 .apply() 而不是:
class TABLE : Tag("table") {
fun tr(init: TR.() -> Unit) {
children += TR().init()
}
}
我想这与编译器在 tr 对象中寻找 init() 有关。但这不应该在运行时决定吗?
正如我在评论中已经建议的那样,使用 .apply
您可以 链 调用 init
和 +=
在一起,因为 apply
returns 调用的目标。
如果您更喜欢使用init()
,您可以使用
获得相同的结果
val tr = TR()
children += tr
tr.init()
chained 变体的关键方面是 applyfunction of the Kotlin's standard library is defined as an extension function of a generic type
T, accepting a *lambda with receiver
作为其唯一参数,如您所见 here:
inline fun <T> T.apply(block: T.() -> Unit): T
为了解释它的意思,你可以自己实现这个功能:
fun <T> T.myApply(block: T.() -> Unit) : T {
this.block()
return this
}
以下示例模仿您的代码,使用伪造的 MyClass
类型代替原始 TR
:
fun <T> T.myApply(block: T.() -> Unit) : T {
this.block()
return this
}
class MyClass(val text: String) {
fun foo() : Unit {
println("foo $text")
}
}
fun initializer(mc: MyClass) {
println("initializer ${mc.text}")
mc.foo()
}
fun run(init: MyClass.() -> Unit) {
val result = MyClass("first").myApply(init)
val x = MyClass("second")
x.init()
}
fun main(args: Array<String>) {
run(::initializer)
}
您可以玩这个例子,以便跟随从 run
到 MyClass.foo
的流程,通过函数接受 init
作为 lambda 和接收器 参数:我希望这可以帮助您阐明对 tr
.
的原始实现和替代实现的关键特征的理解
下面的代码做同样的事情。函数 tr 和 td 以 函数字面量和接收者对象 作为输入,以添加 tr 或table.
内的 td 标签class TABLE : Tag("table") {
fun tr(init: TR.() -> Unit) {
children += TR().apply(init)
}
}
class TR : Tag("tr") {
fun td(init: TD.() -> Unit) {
val td = TD()
td.init()
children += td
}
}
我的问题是为什么我需要使用 .apply() 而不是:
class TABLE : Tag("table") {
fun tr(init: TR.() -> Unit) {
children += TR().init()
}
}
我想这与编译器在 tr 对象中寻找 init() 有关。但这不应该在运行时决定吗?
正如我在评论中已经建议的那样,使用 .apply
您可以 链 调用 init
和 +=
在一起,因为 apply
returns 调用的目标。
如果您更喜欢使用init()
,您可以使用
val tr = TR()
children += tr
tr.init()
chained 变体的关键方面是 applyfunction of the Kotlin's standard library is defined as an extension function of a generic type
T, accepting a *lambda with receiver
作为其唯一参数,如您所见 here:
inline fun <T> T.apply(block: T.() -> Unit): T
为了解释它的意思,你可以自己实现这个功能:
fun <T> T.myApply(block: T.() -> Unit) : T {
this.block()
return this
}
以下示例模仿您的代码,使用伪造的 MyClass
类型代替原始 TR
:
fun <T> T.myApply(block: T.() -> Unit) : T {
this.block()
return this
}
class MyClass(val text: String) {
fun foo() : Unit {
println("foo $text")
}
}
fun initializer(mc: MyClass) {
println("initializer ${mc.text}")
mc.foo()
}
fun run(init: MyClass.() -> Unit) {
val result = MyClass("first").myApply(init)
val x = MyClass("second")
x.init()
}
fun main(args: Array<String>) {
run(::initializer)
}
您可以玩这个例子,以便跟随从 run
到 MyClass.foo
的流程,通过函数接受 init
作为 lambda 和接收器 参数:我希望这可以帮助您阐明对 tr
.