Fungsi toArray
harus mengonversi daftar yang terhapus tipe menjadi T
yaitu Array<String>
sekarang.
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")
Namun, toArray
melemparkan kesalahan ini.
java.lang.ClassCastException: [Ljava.lang.Object; tidak bisa di-cast ke [Ljava.lang.String;
Apakah Anda punya ide?
Masalahnya di sini, adalah Anda sebenarnya mencoba meng-cast Object[]
ke String[]
dalam hal Java, atau Array<Any>
ke Array<String>
dalam hal Kotlin, tetapi ini adalah objek yang berbeda.
Jadi, pernyataan ini:
list.toTypedArray()
mengembalikan Array<Any?>
, dan kemudian Anda mencoba melakukan cast ke Array<String>
dan mendapatkan ClassCastException
.
Saya sarankan untuk mengoper parameter tipe itu sendiri, dan meng-cast List
:
inline fun <reified T> toArray(list: List<*>): Array<T> {
return (list as List<T>).toTypedArray()
}
toArray<String>(listOf("1", "2"))
Saya sarankan untuk menantang kebutuhan Anda untuk mengonversi List<*>
menjadi array yang diketik (misalnya Array<String>
), bukan daftar yang diketik (misalnya List<String>
).
Hal yang terakhir ini dapat dilakukan dengan sangat baik di Kotlin:
list.map { itu sebagai String }
Saya sarankan untuk membaca https://stackoverflow.com/q/36262305/3255152 dan Java Practices -> Prefer Collections over older classes.
Jika Anda masih merasa bahwa Anda perlu bekerja dengan array, maka saya sarankan untuk membuat fungsi "map" yang mirip dengan fungsi "map" yang ada di Kotlin:
kesenangan sebaris < T, R yang direifikasi > Daftar < T > .mapToTypedArray (transform: (T) - > R): Larik < R > {
kembali ketika (ini) {
is RandomAccess -> Array(size) { index -> transform(this[index]) }
else -> with(iterator()) { Array(size) { transform(next()) } }
}
}
Anda kemudian dapat secara efisien mengonversi List<*>
ke larik yang diketik:
list.mapTypedArray { it sebagai String }
Untuk beberapa alasan, saya mendapatkan pengecualian nomor argumen yang tidak valid ketika saya mencoba melakukan ini:
val argumentTypeMirrors = mutableListOf<TypeMirror>()
... // add items to argumentTypeMirrors
val array = argumentTypeMirrors.toTypedArray()
Dan akhirnya saya melakukannya dengan cara ini:
val argumentTypeMirrors = mutableListOf<TypeMirror>()
... // add items to argumentTypeMirrors
val array = Array(argumentTypeMirrors.size) {
argumentTypeMirrors[it]
}
Kemudian saya dapat menghancurkan array
saya dengan *array
untuk meneruskannya sebagai parameter varargs
.