这里有些沉闷的超载:
class Dummy() {
fun f(x: Unit) : String = "Disco"
fun f(x: Unit, y: Unit = Unit) : String = "Mambo"
}
我不确定为什么会这样,但这可行:
fun main(args: Array<String>) {
println(Dummy().f(Unit)) // Echoes “Disco”
}
但是,那不是:
fun main(args: Array<String>) {
println((Dummy::f)(Dummy(), Unit)) // Fails: “Overload resolution ambiguity”
}
对结果差异有何见解?
答案 0 :(得分:1)
当您致电Dummy::f
时,有两个同名的候选人 f :
fun f(x: Unit) : String = "Disco"
fun f(x: Unit, y: Unit = Unit) : String = "Mambo"
然后,编译器不知道采用哪个。这是因为函数参考没有指定参数,即使将其中一个的签名更改为:
fun f(x: Int) : String = "Disco"
fun f(s: String) : String = "Mambo"
您将有一个问题,因为不可能使用以下语句来推断类型:Dummy::f
。
请注意,函数引用主要用于避免创建lambda。
例如,如果您具有:(不同名称)
class Dummy() {
fun f(x: Unit) : String = "Disco"
fun g(x: Int) : String = "Mambo"
}
fun main(args: Array<String>) {
val f = Dummy::f
val g = Dummy::g
}
f
的类型为KFunction2<Dummy, Unit, String>
并且g
类型为KFunction2<Dummy, Int, String>
但是,如果您定义:(同名)
class Dummy() {
fun f(x: Unit) : String = "Disco"
fun f(x: Int) : String = "Mambo"
}
fun main(args: Array<String>) {
val f = Dummy::f
val g = Dummy::f
}
由于将限制编译器的性能,并且由于存在两个具有相同名称的函数,因此无法推断该函数的类型,因此将出现“重载分辨率歧义”错误。要澄清的问题不是参数的数量,而是使用具有许多候选对象的函数引用。
答案 1 :(得分:1)
如果更改函数名称很简单,则只需对其进行更改,
如果您使用的是库或什至是String
之类的原始类,则可以创建如下扩展名:
fun String.myToLowerCase(): String = this.toLowerCase()
fun Dummy.myF(): String = "Disco"
答案 2 :(得分:0)
如果您不能更改其中一个函数的名称来解决歧义引用(例如,因为它们在库中),则还可以创建一个简单的函数代理。
这甚至可以做成扩展功能:
// unchangeable overloaded functions
class Dummy() {
fun f(x: Unit) : String = "Disco"
fun f(x: Unit, y: Unit = Unit) : String = "Mambo"
}
//your code
fun Dummy.g(x:Unit, y:Unit = Unit) = f(x, y)
val functionF = Dummy::f //fine
val functionF2 = Dummy::g //fine