转换容器类型?

也许我错过了一些显而易见的东西……在整个文档中,我认为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()

但是, IntProgressionSequence<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 }