以下语句编译并打印 "fun: called"
:
fun main(vararg args: String) {
fun toCall(arg: String) = println("fun: $arg")
val toCall = fun(arg: String) = println("val: $arg")
toCall("called")
}
注意:如果它们是顶级声明或类内部会出现同样的问题,这只是具有本地函数/变量的最简单的repro .
Looking for clarification on why this compiles in the first place?
What rule comes into play that picks the function over the property?
注意:可以通过以下方式调用 val
:
-
(toCall)("called")
-
toCall.invoke("called")
1 回答
This document regarding name resolution包含有关它的详细信息 .
我将引用一些专门处理您问题的段落 . 它还包含其他几个有趣的东西,但我想我最终会在这里复制一切;-)如果你有兴趣,我只能建议你完全阅读它 .
总结一下,编译器将函数(成员/扩展/成员扩展)/属性分成组并决定首先调用哪一个...属性放在
invoke
-functions的组中,在下面的段落中你已经看到为什么该功能是在val
之前进行的:这就是为什么这个功能首先考虑在这里,后来的属性 . 一旦你指定了
invoke
,很明显它只能是属性,因为函数本身没有可见的invoke
(现在不允许记下字节代码;-)) . 现在(toCall)
表现得与此类似 . 这里很清楚,toCall
只能是 property . 无法使用该函数调用(toCall)
(编译错误:预期函数调用/找不到函数invoke
) .链接文档还包含一个带有成员属性函数的示例,后跟此语句,它基本上也确认了以前关于本地函数的内容: