TWi*_*Rob 5 language-design kotlin
以下语句编译并打印"fun: called":
fun main(vararg args: String) {
fun toCall(arg: String) = println("fun: $arg")
val toCall = fun(arg: String) = println("val: $arg")
toCall("called")
}
Run Code Online (Sandbox Code Playgroud)
注意:如果它们是顶级声明或类内部会出现同样的问题,这只是带有本地函数/变量的最简单的repro.
寻找澄清为什么这首先编译?
什么规则发挥作用,选择财产的功能?
注意:可以val通过以下方式呼叫:
(toCall)("called")toCall.invoke("called")本有关名称解析的文档包含有关它的详细信息。
\n\n我将引用其中专门处理您的问题的一些段落。它还包含其他一些有趣的内容,但我想我最终会复制这里的所有内容;-) 如果您有兴趣,我只能建议您完整地阅读它。
\n\n总而言之,编译器将函数(成员/扩展/成员扩展)/属性分成组,并决定先调用哪一个...属性被放入函数组中invoke,在下面的段落中,您已经明白为什么函数是在您之前执行的val:
\n\n\n该属性与功能一起考虑
\ninvoke。具有函数的属性组与invoke常规函数组混合在一起,从某种意义上说,一组属性可以比一组函数具有更高的优先级,反之亦然。然而,函数和属性不能归为一组:函数总是超越同一类别的属性。属性和invoke函数都决定了组的优先级:我们比较属性和函数的优先级invoke,“最低”的优先级成为组优先级。
这就是为什么这里首先考虑函数,然后考虑属性的原因。一旦您指定,invoke很明显它只能是属性,因为函数本身不可见invoke(现在不要深入字节代码;-))。现在的(toCall)行为类似。这里很清楚,那toCall只能是财产。无法使用(toCall)该函数进行调用(编译错误:需要函数调用/invoke未找到该函数)。
链接的文档还包含一个带有成员属性函数的示例,后跟此语句,这基本上也证实了前面关于局部函数的内容:
\n\n\n\n请注意,没有名为 foo 的成员函数,但如果存在,它将被放入具有最高优先级的单独组中。
\n