3

我试图弄清楚何时使用相同签名的扩展函数覆盖现有的类函数 - 会生效吗?

这是我的示例代码:

fun String.toUpperCase(): String = "ext. function impl."

fun main(args: Array<String>) {

    println("Hello".toUpperCase()) // ext. function impl.

    println(MyClass().toUpperCase()) // class impl.

}

class MyClass {
    fun toUpperCase() : String {
        return "class impl."
    }
}

fun MyClass.toUpperCase() : String {
    return "ext. function impl."
}

所以:

  • 都有些什么样的规矩?什么时候会被调用?
  • 我怎样才能推翻这个决定?是否可以?
4

1 回答 1

4

来自Kotlin 文档(强调不是我的):

如果一个类有一个成员函数,并且定义了一个扩展函数,它具有相同的接收器类型、相同的名称并且适用于给定的参数,则该成员总是会获胜

您的字符串示例有效的原因是库提供String.toUpperCase()已经是扩展函数,而不是成员函数。文档没有说明这里发生了什么,但假设本地扩展获胜似乎是合理的。


我不认为有任何方法可以改变这种行为。这可能是最好的,因为在许多情况下它会违反最小惊讶原则(即难以理解的行为)。

于 2017-08-13T13:18:19.213 回答