运行签名如下:
public inline fun <T, R> T.run(block: T.() -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block()
}
在我看来,回调(块)是通过接收器调用的,但是没有任何参数. 所以为什么有人(在这里有很多学分)对我说:1。
thing.run(::println)
等价于:
2。
thing.run { println(this) }
我完全不明白第一个是怎么运行的…因为我看到的方式是println不会得到任何参数
当您通过使用函数引用语法而不是lambda将函数传递给高阶函数时,是否有接收器并不重要。接收方和其他参数一样,可以看作是第一个参数。
所以run函数参数的语法:
T.() -> R
的语法将与let的函数参数的语法完全相同:
(T) -> R
所以::println
可以匹配其中任何一个
这也适用于另一个方向。当使用函数引用语法传递扩展函数或成员函数时,扩展函数的接收者被视为第一个参数。
val list = listOf(1, 2, 3)
list.run(List<Int>::sum)
list.let(List<Int>::sum)
所以是否有接收器只影响lambda。实际的函数签名是相同的。如果您尝试这样定义两个函数,就会看到这个问题。对于具有相同签名的两个函数,将会出现编译错误:
class Foo
fun bar(foo: Foo) {
println("Hello")
}
fun Foo.bar() {
println("Hello")
}