转换容器类型?
也许我错过了一些显而易见的东西……在整个文档中,我认为Kotlin有各种各样的序列,这些序列是不能互操作的。 即使复制一个序列效率低下 – 当我需要将它传递给一个语义相同但类型不同的函数时,这是无法帮助的。 所以我想出了这些构造函数和转换器(仅用于Int和一种方式):
fun IntArray(a: Array<Int>) = IntArray( a.size ) { a[it] } fun IntArray(c: Collection<Int>) = IntArray( c.size ) { c.elementAt(it) } fun IntArray(p: IntProgression) = IntArray( p.toList() ) fun IntArray(s: Sequence<Int>) = IntArray( s.toList() ) fun Array<Int>.toIntArray() = IntArray( this ) fun Collection<Int>.toIntArray() = IntArray( this ) fun IntProgression.toIntArray() = IntArray( this ) fun Sequence<Int>.toIntArray() = IntArray( this ) /* If constructors are not desirable: fun Array<Int>.toIntArray() = IntArray( size ) { get(it) } fun Collection<Int>.toIntArray() = IntArray( size ) { elementAt(it) } fun IntProgression.toIntArray() = toList().toIntArray() fun Sequence<Int>.toIntArray() = toList().toIntArray()*/
有没有理由不在标准库中包含所有这些变体,也许是内联的呢? 第三个甚至允许一个很好的初始化语法:
val ia = IntArray( 7 .. 11 )
实际上,stdlib中有一些函数用于执行转换:请参阅.toIntArray()
,它适用于Array<out Int>
和Collection<Int>
。 其他原始类型也有这样的转换: .toLongArray()
.toByteArray()
等
但是, IntProgression
和Sequence<Int>
没有这样的扩展,您必须自己实现它,或者使用中间数组或集合。
可能的原因是没有鼓励在代码中使用数组,除了性能关键部分,而是使用列表和其他集合的习惯用法。
另外,三种Kotlin容器Collection<T>
, Sequence<T>
和Array<T>
可以互相转换,参见:
-
.asSequence()
-
.toTypedArray()
(似乎缺少Sequence<T>
) -
.toCollection()
(和Sequence<T>
.toCollection()
)
Array<Int>
和IntArray
不能互操作,因为它们是非常不同的类型。 第一个映射到Integer[]
,第二个映射到int[]
。 原始的int[]
会更高效,因为它是连续存储的,而第一个实质上是分配一个对象数组,每个槽指向一个Integer
对象。 内存使用情况和性能将大大优于int[]
。
Kotlin喜欢明确这些类型的东西,正如你所指出的那样,当你需要的时候写下你自己的转换需要一行。
PS:看起来Kotlin确实有从数字Collection
到原始数组的扩展功能:
public fun Collection<Int>.toIntArray(): IntArray { val result = IntArray(size) var index = 0 for (element in this) result[index++] = element return result }