Kotlin中的IntArray与Array <Int>


88

我不确定在Kotlin中anIntArray和an之间的区别是什么Array<Int>,为什么我不能互换使用它们:

错配

我知道IntArrayint[]定位到时JVMArray<Int>转化为,但是转化为什么?

另外,您也可以拥有String[]YourObject[]。为什么Kotlin拥有类型的类,而{primitive}Array几乎所有东西都可以排列成数组,而不仅仅是原语。


1
我的猜测Array<Int>编译到Integer[](如果编译器没有对此进行优化)
Mibac


是的,这很有意义,谢谢你们!
FRR

Answers:


107

Array<Int>Integer[]引擎盖下的,IntArray而是int[]。而已。

这意味着,当你把一个IntArray<Int>,它都会被装箱(具体地讲,与Integer.valueOf()呼叫)。在的情况下IntArray,不会进行装箱,因为它会转换为Java基本数组。


除了上述可能对性能的影响外,还需要考虑一些便利。原始数组可以不初始化,并且0在所有索引处都将具有默认值。这就是为什么IntArray其余的原始数组都具有仅采用size参数的构造函数:

val arr = IntArray(10)
println(arr.joinToString()) // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

相反,Array<T>没有一个仅带有size参数的构造函数:创建后,它需要T所有索引处的有效非空实例才能处于有效状态。对于Number类型,这可能是默认值0,但是无法创建任意类型的默认实例T

因此,在创建时Array<Int>,您也可以使用带有初始化函数的构造函数:

val arr = Array<Int>(10) { index -> 0 }  // full, verbose syntax
val arr = Array(10) { 0 }                // concise version

或创建一个Array<Int?>以避免必须初始化每个值,但是稍后您null每次从数组中读取数据时都会被迫处理可能的值。

val arr = arrayOfNulls<Int>(10)

4
这是很愚蠢的决定。因此,他们必须为每种原始类型创建一个新类……他们可以使用与Java相同的类。
Android开发人员

1
@androiddeveloper什么新类?int[]IntArrayInteger[]Array<Int>,依此类推,这个神秘的新班级在哪里?只是语法不同,这是同一件事。int[]顺便说一句,它也是上课的。
Eugen Pechanec

1
@EugenPechanec这很有趣。他们说这是一个类,并且有一个实例,但是“该类的实例也表示为int []”:kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int-array/…。那么,这些功能仅仅是扩展功能,还是属于真实类?又为什么需要有“ IntArray”和其他?仍可以使用Java语法完成。
Android开发人员

1
@EugenPechanec但是在Java中,int []不是一个类,不是吗?它是一个对象,一组原始体。您无法到达或扩展代码。没有?Java上的所有类的名称均带有大写字母。这里不是。
Android开发者

1
@EugenPechanec因此,在Kotlin上它是一个类,而在Java上则不是。仍然不明白为什么。他们可以添加扩展功能,不是吗?您也许可以从IntArray扩展?关于命名,我知道。这只是约定,也是一个好的约定。
Android开发人员


1

Kotlin中的数组是类(不是Java的“特殊”类型)。

Kotlin的stdlib为JVM基本数组提供了特殊用途的类,以改善Java语言的集成和性能。

经验法则是使用,Array<T>除非它在与现有Java代码混合时会引起问题,或者应该从Java类中调用。出于记录,我从未使用过IntArray

您可以在此处查看有关此问题的语言文档:https : //kotlinlang.org/docs/reference/basic-types.html#arrays


我相信您总是对Array <T>胜过IntArray是正确的,我担心使用盒装类型vs原语的装箱/拆箱开销,但是Kotlin似乎很聪明,可以决定是否可以使用原语。(如果我做错了,请纠正我)“在Java平台上,除非我们需要可为空的数字引用(例如Int?)或涉及泛型,否则数字在物理上存储为JVM基本类型。在后一种情况下,将数字装箱。” 来自kotlinlang.org/docs/reference/basic-types.html
FRR

@feresr不以任何方式的专家,但我认为这仅仅是指到的实现IntFloat因为科特林不会有不同的类型,等等,Booleanboolean。就数组而言,我认为这Array<Int>与有所不同IntArray。我个人一直使用后者,因为它从来没有打扰过我,但是Kotlin可能还有我不知道的其他优化。如果您仅使用Kotlin进行编程,那么在任何情况下您都不需要一个,但是原始数组可能仍然有其优点。
艾伦W

@AllanW也不是专家,只是好奇,我相信Java同时具有基元和装箱的对象,因为使用基元更有效吧?当然,有时您确实需要使用对象(可空性/泛型)。这超出了我最初提出的问题的范围,但是我想知道Kotlin在针对JVM时如何处理这个问题。我尝试尽可能使用IntArray(认为它是在后台使用基本体),但是在@ jamming评论之后,我不确定。
FRR

1
@feresr对我来说,Kotlin的文档明确指出特殊数组实例在那里,以避免装箱开销。我得出的结论是,两者可能有所不同,最终对于开发人员而言,这与决定要在Java中使用Integer []还是int []一样。
艾伦W

我同意,那么接受的答案可能会误导新人,因此,我未将其标记为接受的答案。
FRR
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.