转换容器类型?

时间:2017-05-21 19:56:27

标签: type-conversion kotlin

也许我错过了一些明显的东西......在我看来,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 )

2 个答案:

答案 0 :(得分:4)

实际上,stdlib中有一些功能可以进行转换:请参阅.toIntArray(),它与Array<out Int>Collection<Int>一起使用。其他原始类型也有这样的转换:.toLongArray().toByteArray()等。

但是,IntProgressionSequence<Int>没有此类扩展名,您必须自行实施或使用中间数组或集合。

这种缺席的原因可能是你不鼓励你在你的代码中使用数组,除了性能关键部分,而不是使用列表和其他集合的惯用语。

此外,三种Kotlin容器Collection<T>Sequence<T>Array<T>可以相互转换,请参阅:

答案 1 :(得分:2)

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
}