mmo*_*iro 16 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")
Run Code Online (Sandbox Code Playgroud)
但是,toArray抛出此错误.
java.lang.ClassCastException:[Ljava.lang.Object; 无法转换为[Ljava.lang.String;
你有什么想法?
Rus*_*lan 42
这里的问题是,你实际上是试图投Object[]以String[]Java中的条款,或者Array<Any>以Array<String>在科特林方面,但这是不同的对象.
所以,这句话:
list.toTypedArray()
Run Code Online (Sandbox Code Playgroud)
返回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"))
Run Code Online (Sandbox Code Playgroud)
要了解为什么会发生这种情况,我建议阅读Kotlin和Java 实践中列表和数组类型之间的差异-> 首选集合而不是旧类。
一般来说,我建议使用列表而不是数组,但如果您想在 Kotlin 中将类型擦除列表转换为数组,最简单的方法是首先映射到类型列表,然后转换为类型数组:
list.map { it as String }.toTypedArray()
Run Code Online (Sandbox Code Playgroud)
如果您实际上不需要数组但类型列表可以,那么您可以简单地将类型擦除列表映射到类型列表:
list.map { it as String }
Run Code Online (Sandbox Code Playgroud)
如果您发现自己经常将类型擦除列表转换为数组并且性能很重要,那么我建议创建一个为此优化的映射函数,同时避免中间列表:
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()) } }
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以有效地将 a 转换List<*>为类型化数组:
list.mapToTypedArray { it as String }
Run Code Online (Sandbox Code Playgroud)