高阶 'run' 函数块在 Kotlin 中如何工作?
How does high order 'run' function block work in Kotlin?
运行 签名看起来像:
public inline fun <T, R> T.run(block: T.() -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block()
}
在我看来,回调 (block) 是通过接收器调用的,但是 没有任何参数。所以有人(在这里有很多学分)是怎么说的:
1.
thing.run(::println)
等同于:
2.
thing.run { println(this) }
我根本无法理解第一个是如何 运行ning...因为我看到它的方式 println 不会得到任何参数
当您使用函数引用语法而不是 lambda 将函数传递给高阶函数时,是否有接收者并不重要。接收器与任何其他参数一样,可以认为是第一个参数。
所以运行的函数参数的语法:
T.() -> R
将被视为与 let's 函数参数的语法完全相同:
(T) -> R
所以 ::println
可以匹配其中任何一个。
反之亦然。当您使用函数引用语法传递扩展函数或成员函数时,扩展函数的接收者被视为第一个参数。以下任何一个都有效:
val list = listOf(1, 2, 3)
list.run(List<Int>::sum)
list.let(List<Int>::sum)
所以是否有接收者只影响lambdas。实际的函数签名是相同的。如果您尝试像这样定义两个函数,就会看到此问题。具有相同签名的两个函数将出现编译错误:
class Foo
fun bar(foo: Foo) {
println("Hello")
}
fun Foo.bar() {
println("Hello")
}
运行 签名看起来像:
public inline fun <T, R> T.run(block: T.() -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block()
}
在我看来,回调 (block) 是通过接收器调用的,但是 没有任何参数。所以有人(在这里有很多学分)是怎么说的:
1.
thing.run(::println)
等同于:
2.
thing.run { println(this) }
我根本无法理解第一个是如何 运行ning...因为我看到它的方式 println 不会得到任何参数
当您使用函数引用语法而不是 lambda 将函数传递给高阶函数时,是否有接收者并不重要。接收器与任何其他参数一样,可以认为是第一个参数。
所以运行的函数参数的语法:
T.() -> R
将被视为与 let's 函数参数的语法完全相同:
(T) -> R
所以 ::println
可以匹配其中任何一个。
反之亦然。当您使用函数引用语法传递扩展函数或成员函数时,扩展函数的接收者被视为第一个参数。以下任何一个都有效:
val list = listOf(1, 2, 3)
list.run(List<Int>::sum)
list.let(List<Int>::sum)
所以是否有接收者只影响lambdas。实际的函数签名是相同的。如果您尝试像这样定义两个函数,就会看到此问题。具有相同签名的两个函数将出现编译错误:
class Foo
fun bar(foo: Foo) {
println("Hello")
}
fun Foo.bar() {
println("Hello")
}