我来自C#背景,我知道如何在C#中实现这一点,但我正在努力使用Kotlin。我有两个扩展函数:
fun <T> Foo<T>.myFunction(func: () -> Unit): Foo<T>
和
fun <T> Foo<T>.myFunction(func: () -> Foo<T>): Foo<T>
显然,func的返回类型在两个函数中是不同的。第一个函数执行它并返回this,第二个函数执行func并返回func的结果。但它给了我一个错误:
“平台宣言冲突:以下声明具有相同的JVM签名”“。
如何在Kotlin中正确实现这一点?
3条答案
按热度按时间0aydgbwb1#
由于类型擦除(* 内部 *
Function0<T>
* 类用于表示函数参数 *),您的函数在JVM中具有冲突的签名;你可以通过给它们每个一个JVM特定的名字来解决这个问题。在Kotlin中,你仍然可以用原来的名字访问它们,但是在Java或内部,实际上使用了另一个名字。只需在替代版本上使用@JvmName
注解:rqdpfwrv2#
在JVM上,我们必须使用contend with type erasure。本质上意味着类型(在本例中为
T
)在编译后的字节码中被丢弃,并且所需的检查仅在编译时完成。考虑到这一点,你必须考虑到这一点来看待你的函数声明。在这两种情况下,Kotlin都会将函数参数定义为
Function0
。因为类型被擦除,所以() -> Unit
和() -> Foo<T>
在字节码中看起来是一样的。我们可以通过反编译您提供的代码来证明这一点(我将其中一个重命名为myFunction2
以使其工作):这就是Kotlin编译器正在生成的内容(它做的更多,但我已经从这个例子中删除了不必要的部分)。正如你所看到的,由于类型擦除,我们的类型消失了。如果我们撤销我的更改(
myFunction2
变成myFunction
),就根本没有办法区分它们。这就是编译器所抱怨的--如果你删除了JVM无法区分这些函数的类型。cclgggtu3#
1.请更改您的fragmentManager名称,因为您的参数作为fragmentManager,它将与基类参数名称(默认情况下也是fragmentManager)反转。因此,更改参数的名称将对您有所帮助。