IntArray vs Array <Int> в Котлине

Я не уверен, какая разница между IntArray и Array<Int> в Kotlin и почему я не могу использовать их взаимозаменяемо:

missmatch

Я знаю, что IntArray переводит на int[] при таргетинге на JVM, но что означает Array<Int> для перевода на?

Кроме того, вы также можете иметь String[] или YourObject[]. Почему у Котлина есть классы типа {primitive}Array, когда в массив можно вместить что угодно, а не только примитивы.

Ответ 1

Array<Int> является целым Integer[] под капотом, а IntArray - int[]. Это.

Это означает, что когда вы помещаете Int в Array<Int>, он всегда будет помещен в коробку (в частности, с Integer.valueOf()). В случае с IntArray никакого бокса не будет, потому что он переводится в примитивный массив Java.


Помимо возможных последствий для работы вышеизложенного, есть также удобство для рассмотрения. Примитивные массивы могут быть оставлены неинициализированными, и они будут иметь значения по умолчанию 0 во всех индексах. Вот почему IntArray и остальные примитивные массивы имеют конструкторы, которые принимают только параметр размера:

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

Напротив, Array<T> не имеет конструктора, который принимает только параметр размера: ему нужны действительные, не нулевые экземпляры 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)

Ответ 2

Массивы в Котлине являются классами (а не "специальными" типами, такими как Java).

Kotlin stdlib предоставляет классы специального назначения для примитивных массивов JVM, чтобы улучшить интеграцию и производительность языка Java.

Правило большого пальца будет заключаться в использовании Array<T>, за исключением случаев, когда это вызывает проблему при смешивании с существующим Java-кодом или должно быть вызвано из классов Java. Для записи мне никогда не приходилось использовать IntArray.

Вы можете проверить документацию по этому вопросу здесь: https://kotlinlang.org/docs/reference/basic-types.html#arrays

Ответ 3

Стоит отметить, что использование оператора spread (*) в vararg вернет IntArray. Если вам нужен Array<Int>, вы можете преобразовать IntArray с помощью .toTypedArray().