我有两个Kotlin扩展方法用于同一个类,但具有不同的通用签名,编译器抱怨

Jay*_*ard 15 generics extension-methods kotlin

我正在为同一个类编写两个扩展函数:

class Something<T:Any> { ... }
Run Code Online (Sandbox Code Playgroud)

他们看着像是:

fun Something<Int>.toJson(): String = ...
fun Something<Double>.toJson(): String = ...
Run Code Online (Sandbox Code Playgroud)

并导致编译器错误:

Kotlin:平台声明冲突:以下声明具有相同的JVM签名

如何创建两个扩展函数,只有泛型签名不同?还是不可能?

注意: 这个问题是由作者故意编写和回答的(答案问题),因此常见问题的Kotlin主题的答案存在于SO中.它起源于Kotlin松弛的 #general通道.

Jay*_*ard 21

Kotlin 专门针对此类用例进行了@JvmName注释.在Kotlin中,没有问题,因为它知道方法之间的区别.但是Java兼容的字节代码会对命名产生冲突,因为泛型擦除的签名将是相同的.

因此,您需要使用此批注从Java和JVM的角度控制名称.您的Kotlin代码将不会看到此替代名称,并将按预期使用该名称.

将您的代码更改为:

@JvmName("somethingIntToJson") fun Something<Int>.toJson(): String = ...
@JvmName("somethingDoubleToJson") fun Something<Double>.toJson(): String = ...
Run Code Online (Sandbox Code Playgroud)

从Kotlin,正常使用:

val someIntyThing = Something<Int>(194)
val json = someIntyThing.toJson()
Run Code Online (Sandbox Code Playgroud)