高阶 '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")
}