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

I have two Kotlin extension methods for the same class, but with a different generic signatures and the compiler complains

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

class Something<T:Any> { ... }

它们看起来像:

fun Something<Int>.toJson(): String = ...
fun Something<Double>.toJson(): String = ...

并导致编译器错误:

Kotlin: Platform declaration clash: The following declarations have the same JVM signature

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

注:这个问题是作者故意写的,并且是作者回答的(Self-Answered Questions), so that the answers to commonly asked Kotlin topics are present in SO. It originated in Kotlin slack#general channel.

Kotlin 有专门针对此类用例的 @JvmName annotation。在 Kotlin 中,没有问题,因为它知道方法之间的区别。但是 Java 兼容的字节码在命名上会有冲突,因为泛型擦除签名是相同的。

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

将您的代码更改为:

@JvmName("somethingIntToJson") fun Something<Int>.toJson(): String = ...
@JvmName("somethingDoubleToJson") fun Something<Double>.toJson(): String = ...

来自 Kotlin,正常使用:

val someIntyThing = Something<Int>(194)
val json = someIntyThing.toJson()