为什么在Kotlin中可以将高阶函数的扩展函数参数作为常规函数调用?

TWi*_*Rob 5 extension-methods compilation higher-order-functions kotlin

让我们考虑以下代码:

class Receiver

fun higherOrder(extensionBlock: Receiver.() -> Unit) {
    Receiver().extensionBlock() // works
    extensionBlock(Receiver()) // works
}

fun Receiver.extension() = Unit
fun f() {
    Receiver().extension() // works
    extension(Receiver()) // unresolved reference
}
Run Code Online (Sandbox Code Playgroud)

在我看来,扩展的功能签名是Receiver.() -> Unit,与extensionBlock参数的相同;即我们可以打电话给我higherOrder(Receiver::extension)。如果是这样,我不明白为什么扩展函数和相同类型的参数之间的常规函数​​调用语法不一致。我真的很高兴这extension(Receiver())是不允许的,所以只有一种方法可以调用扩展功能。所以我想主要的问题是,为什么extensionBlock(Receiver())extensionBlock有扩展功能签名的情况下可以做什么?

Rol*_*and 4

也许查看字节码有帮助......

extensionBlock : Receiver.() -> Unit是一个Function1<Receiver, Unit>. 在幕后,这两个调用基本上类似于extensionBlock.invoke(Receiver())...(您甚至可以在比较中编写那个调用...)...所以编译器实现了两者都起作用的魔力...为什么它不这样做那也在扩展变体中吗?

扩展函数只是以接收者作为参数的静态函数。现在猜测为什么它不以与高阶函数相同的方式得到支持,尽管在技术上这是可能的。有了如下的东西,它也应该是一个扩展函数吗?

fun extension(r : Receiver) = Unit // to extend or not to...?
Run Code Online (Sandbox Code Playgroud)

我认为它应该,如果你想支持extension(Receiver())扩展函数(并且从字节码来看没有区别)。目前,您无法同时拥有这两个函数,因为您会遇到平台声明冲突(这基本上说明了为什么extension(Receiver())应该使用扩展函数)。

我想知道如果是这样的话,编译器处理的逻辑是否会或多或少......说实话,我喜欢高阶函数和扩展函数在这方面有所不同......对我来说,扩展函数或扩展函数以某些东西作为参数的函数是两种不同类型的东西...如果扩展函数可以以两种方式使用,即extension(Receiver())Receiver().extension()...如果〜普通函数也可用,可能会更令人困惑作为扩展函数...

遗憾的是,但也是合乎逻辑的,这在 Java 端是有效的:(<WrapperClass>.extension(new Receiver())但我们在那里没有真正的扩展,所以没关系;-))