首页 文章

如何解析具有相同名称的Kotlin函数/属性?

提问于
浏览
5

以下语句编译并打印 "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 回答

  • 1

    This document regarding name resolution包含有关它的详细信息 .

    我将引用一些专门处理您问题的段落 . 它还包含其他几个有趣的东西,但我想我最终会在这里复制一切;-)如果你有兴趣,我只能建议你完全阅读它 .

    总结一下,编译器将函数(成员/扩展/成员扩展)/属性分成组并决定首先调用哪一个...属性放在 invoke -functions的组中,在下面的段落中你已经看到为什么该功能是在 val 之前进行的:

    该属性与调用函数一起考虑 . 具有调用函数的属性组与常规函数组混合,在某种意义上,一组属性可以具有比一组函数更高的优先级,反之亦然 . 但是,函数和属性不能放在一个组中:函数总是超过同一类别的属性 . 属性和调用函数都确定组的优先级:我们比较属性和调用函数的优先级,“最低”的优先级成为组优先级 .

    这就是为什么这个功能首先考虑在这里,后来的属性 . 一旦你指定了 invoke ,很明显它只能是属性,因为函数本身没有可见的 invoke (现在不允许记下字节代码;-)) . 现在 (toCall) 表现得与此类似 . 这里很清楚, toCall 只能是 property . 无法使用该函数调用 (toCall) (编译错误:预期函数调用/找不到函数 invoke ) .

    链接文档还包含一个带有成员属性函数的示例,后跟此语句,它基本上也确认了以前关于本地函数的内容:

    请注意,没有名为foo的成员函数,但如果它存在,则会将其放入具有最高优先级的单独组中 .

相关问题