如何在Kotlin中将类型擦除列表转换为数组?

时间:2016-12-24 10:55:29

标签: arrays list kotlin

函数toArray应将类型清除列表转换为T 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")

但是,toArray会抛出此错误。

  

java.lang.ClassCastException:[Ljava.lang.Object;无法转换为[Ljava.lang.String;

你有什么想法吗?

3 个答案:

答案 0 :(得分:39)

问题在于,您实际上是尝试使用Java来Object[]转换为String[],或者根据Kotlin将Array<Any>转换为Array<String>,但这是不同的对象

所以,这句话:

list.toTypedArray()

返回Array<Any?>,然后您尝试将其投放到Array<String>并获取ClassCastException

如何解决?

我建议传递类型参数本身,并投射List

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

toArray<String>(listOf("1", "2"))

答案 1 :(得分:3)

  1. 我建议您强烈要求将List<*>转换为类型化数组(例如Array<String>)而不是类型化列表(例如List<String>)。

    后者可以在Kotlin中很好地完成:

    list.map { it as String }
    

    我建议您阅读Difference between List and Array types in KotlinJava Practices -> Prefer Collections over older classes

  2. 如果您仍然觉得需要使用数组,那么我建议您创建一个类似于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()) } }
        }
    }
    

    然后,您可以有效地将List<*>转换为类型化数组:

    list.mapToTypedArray { it as String }
    

答案 2 :(得分:0)

出于某种原因,当我尝试这样做时,我得到了无效的参数编号异常:

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

我最终这样做了:

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

然后,我可以使用array销毁我的*array,并将其作为varargs参数传递。

相关问题