web-dev-qa-db-de.com

Wie konvertiert man eine typengelöschte Liste in ein Array in Kotlin?

Eine Funktion toArray sollte jetzt die vom Typ gelöschte Liste in T konvertieren, die jetzt Array<String> ist.

inline fun <reified T> toArray(list: List<*>): T {
    return list.toTypedArray() as T
}

toArray<Array<String>>(listOf("a", "b", "c")) // should be arrayOf("a", "b", "c")

toArray gibt jedoch diesen Fehler aus.

Java.lang.ClassCastException: [Ljava.lang.Object; kann nicht in [Ljava.lang.String;

Hast du eine Idee?

14
mmorihiro

Das Problem hierbei ist, dass Sie tatsächlich versuchen, Object[] in String[] in Bezug auf Java oder Array<Any> in Array<String> in Bezug auf Kotlin umzuwandeln.

Also diese Aussage:

list.toTypedArray()

gibt Array<Any?> zurück und versucht dann, es in Array<String> umzuwandeln und ClassCastException abzurufen. 

Wie repariert man?

Ich schlage vor, den Parameter type selbst zu übergeben und List umzuwandeln:

inline fun <reified T> toArray(list: List<*>): Array<T> {
    return (list as List<T>).toTypedArray()
}

toArray<String>(listOf("1", "2"))
34
IRus
  1. Ich empfehle Ihnen die Herausforderung, einen List<*> in ein typisiertes Array (z. B. Array<String>) anstelle einer typisierten Liste (z. B. List<String>) zu konvertieren.

    Letzteres kann in Kotlin sehr gut gemacht werden:

    list.map { it as String }
    

    Ich empfehle das Lesen von Unterschied zwischen List- und Array-Typen in Kotlin und Java Practices -> Sammlungen vorrangig vor älteren Klassen .

  2. Wenn Sie immer noch das Gefühl haben, mit Arrays arbeiten zu müssen, empfiehlt es sich, eine "Map" -Funktion zu erstellen, die den verschiedenen "Map" -Funktionen von Kotlin ähnelt:

    inline fun <T, reified R> List<T>.mapToTypedArray(transform: (T) -> R): Array<R> {
        return when (this) {
            is RandomAccess -> Array(size) { index -> transform(this[index]) }
            else -> with(iterator()) { Array(size) { transform(next()) } }
        }
    }
    

    Sie können dann einen List<*> effizient in ein typisiertes Array konvertieren:

    list.mapToTypedArray { it as String }
    
3
mfulton26

Aus irgendeinem Grund bekam ich eine ungültige Argumentnummer-Ausnahme, als ich dies versuchte:

val argumentTypeMirrors = mutableListOf<TypeMirror>()
... // add items to argumentTypeMirrors
val array = argumentTypeMirrors.toTypedArray()

Und am Ende habe ich es so gemacht:

val argumentTypeMirrors = mutableListOf<TypeMirror>()
... // add items to argumentTypeMirrors
val array = Array(argumentTypeMirrors.size) {
    argumentTypeMirrors[it]
}

Dann konnte ich meine array mit *array zerstören, um sie als varargs-Parameter zu übergeben.

0
epool