Une fonction toArray
devrait convertir la liste de types effacés en T
qui correspond maintenant à Array<String>
.
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")
Cependant, toArray
lève cette erreur.
Java.lang.ClassCastException: [Ljava.lang.Object; ne peut pas être converti en [Ljava.lang.String;
Avez-vous des idées?
Le problème ici est que vous essayez réellement de transtyper Object[]
en String[]
en termes de Java, ou de Array<Any>
en Array<String>
en termes de Kotlin, mais il s'agit d'objets différents.
Donc, cette déclaration:
list.toTypedArray()
renvoie Array<Any?>
et vous essayez ensuite de le transtyper en Array<String>
et obtenez ClassCastException
.
Je suggère de passer le paramètre de type lui-même et de transtyper List
:
inline fun <reified T> toArray(list: List<*>): Array<T> {
return (list as List<T>).toTypedArray()
}
toArray<String>(listOf("1", "2"))
Je vous recommande de contester votre besoin de convertir un List<*>
en un tableau typé (par exemple Array<String>
) au lieu d'une liste typée (par exemple List<String>
).
Ce dernier peut être très bien fait à Kotlin:
list.map { it as String }
Je recommande de lire Différence entre les types List et Array dans Kotlin et Pratiques Java -> Préférer les collections aux anciennes classes .
Si vous pensez toujours que vous devez travailler avec des tableaux, je vous recommande de créer une fonction "map" similaire aux différentes fonctions "map" de Kotlin:
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()) } }
}
}
Vous pouvez ensuite convertir efficacement un List<*>
en un tableau typé:
list.mapToTypedArray { it as String }
Pour une raison quelconque, je recevais une exception de numéro d'argument non valide lorsque j'essayais de le faire:
val argumentTypeMirrors = mutableListOf<TypeMirror>()
... // add items to argumentTypeMirrors
val array = argumentTypeMirrors.toTypedArray()
Et j'ai fini par le faire de cette façon:
val argumentTypeMirrors = mutableListOf<TypeMirror>()
... // add items to argumentTypeMirrors
val array = Array(argumentTypeMirrors.size) {
argumentTypeMirrors[it]
}
Ensuite, j'ai pu détruire ma array
avec *array
pour la transmettre en tant que paramètre varargs
.