kotlin - 用于重载的JvmName使代码得以编译,但是在调用函数时会引发错误

标签 kotlin

在另一个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() }

最佳答案

我想我可以看到这里发生了什么。您正在执行以下操作:

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。您可以在此处检查相关问题,也可以添加自己的问题。

关于kotlin - 用于重载的JvmName使代码得以编译,但是在调用函数时会引发错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51581179/

相关文章:

java - 我是否应该使用一个 POJO 类来表示从 Room Table 返回的所有可能的列?

kotlin - 如何初始化lateinit变量?

java - 如何调整ScrollView中的Banner广告

android - 当前使用的布局是横向还是纵向?

Android导航组件不显示 fragment

kotlin - 如何让我的 JS 测试出现在 Kotlin 多平台项目中

android - 清除共享 View 模型

java - 如何在Android中滚动项目时添加圆角作为Recyclerview的背景

Spring 数据预测

android - Unresolved reference :build.gradle.kts中的grgit