从另一个question开始,我正在尝试调用2个函数:
@JvmName("myFunction1")
fun <T> Foo<T>.myFunction(func: () -> Foo<Any>): Foo<T>
和
@JvmName("myFunction2")
fun <T> Foo<T>.myFunction(func: () -> Unit): Foo<T>
但我收到此错误:
Cannot choose among the following candidates without completing type inference:
@JvmName public fun <T> Foo<Any>.myFunction(func: () → Foo<Any>): Foo<Any> defined in common.result
@JvmName public fun <T> Foo<Any>.myFunction(func: () → Unit): Foo<Any> defined in common.result
有人知道如何解决此问题吗?
我试图按以下方式调用函数:
myFoo.myFunction{ methodReturningUnit() }
myFoo.myFunction{ methodReturningFooOfAny() }
答案 0 :(得分:2)
我想我可以看到这里发生了什么。您正在执行以下操作:
class Foo<T> {}
@JvmName("myFunction1")
fun <T> Foo<T>.myFunction(func: () -> Foo<T>): Foo<T> {
// ...
}
@JvmName("myFunction2")
fun <T> Foo<T>.myFunction(func: () -> Unit): Foo<T> {
// ...
}
// call the function, but get a compiler error
fooInstance.myFunction { somethingThatReturnsFooAny() } // ERROR!
所以错误是因为编译器试图通过使用传递给它的方法签名来推断lambda函数的类型(因为这将指示传入的参数和退出的结果),但是函数本身具有不明确的声明,仅在返回类型上有所不同。因此,我认为循环类似于:首先可以从调用的函数推断出lambda输入参数,然后知道返回类型,并且可以对lambda强制执行该返回类型。由于匹配参数列表,因此无法完成该循环。我认为返回类型就足够了,但这似乎是类型推断系统中同时向两个方向发展的一个漏洞。
您可以执行的操作有点丑陋,但是请键入函数调用:
fooInstance.myFunction(fun ():Foo<Any> { return somethingThatReturnsFooAny() })
或
val funcy = fun (): Foo<Any> { return somethingThatReturnsFooAny() }
fooInstance.myFunction(funcy)
这样编译器不必猜测两个方向,也不必缺少信息。
大多数类型推断已知错误均作为此问题的子级列出:KT-11289。您可以在此处查看相关问题,也可以添加自己的问题。