2016-02-23 2 views
13

Ich schreibe zwei Erweiterungsfunktionen für die gleiche Klasse:Ich habe zwei Kotlin Erweiterungsmethoden für die gleiche Klasse, aber mit einer anderen generischen Signaturen und dem Compiler beschwert

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

Sie sehen aus wie:

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

und führt zu dem Compiler-Fehler:

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

Wie kann ich zwei Erweiterungsfunktionen erstellen, bei denen sich nur die Generics-Signatur unterscheidet? oder ist das nicht möglich?

Hinweis:diese Frage absichtlich geschrieben und beantwortet vom Autor (Self-Answered Questions), so dass die Antworten auf häufig gestellte Kotlin Themen in SO vorhanden sind. Es entstand in Kotlin slack # general channel.

Antwort

17

Kotlin hat die @JvmName annotation speziell für diese Art von Anwendungsfall. In Kotlin gibt es kein Problem, weil es den Unterschied zwischen den Methoden kennt. Aber der Java-kompatible Byte-Code hätte einen Konflikt bei der Benennung, da die generischen gelöschten Signaturen identisch wären.

Daher müssen Sie diese Annotation verwenden, um den Namen aus der Perspektive von Java und der JVM zu steuern. Ihr Kotlin-Code wird diesen alternativen Namen nicht sehen und wird den Namen wie gewünscht verwenden.

Ihren Code ändern:

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

Von Kotlin, verwenden in der Regel:

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

dies auch für parametrisierte Lambda Argumente funktioniert – Antek

Verwandte Themen