Nie jestem pewien, jaka jest różnica między an IntArray
i an Array<Int>
w Kotlinie i dlaczego nie mogę ich używać zamiennie:
Wiem, że to się IntArray
przekłada, int[]
gdy kierujemy na JVM
, ale co się Array<Int>
przekłada?
Możesz także mieć String[]
lub YourObject[]
. Dlaczego Kotlin ma klasy tego typu, {primitive}Array
skoro w tablicy można umieścić prawie wszystko, nie tylko prymitywy.
Array<Int>
gromadzi doInteger[]
(jeśli kompilator nie zoptymalizować)Odpowiedzi:
Array<Int>
jestInteger[]
pod maską, aIntArray
jestint[]
. Otóż to.Oznacza to, że jeśli umieścić
Int
w sposóbArray<Int>
, to zawsze będzie ramkach (w szczególności zInteger.valueOf()
połączenia). W przypadkuIntArray
formatu boksowanie nie nastąpi, ponieważ przekłada się to na tablicę prymitywną języka Java.Poza możliwymi konsekwencjami powyższego dla wydajności, należy wziąć pod uwagę również wygodę. Tablice prymitywne mogą pozostać niezainicjowane i będą miały
0
wartości domyślne we wszystkich indeksach. Oto dlaczego,IntArray
a pozostałe tablice pierwotne mają konstruktory, które przyjmują tylko parametr rozmiaru:val arr = IntArray(10) println(arr.joinToString()) // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
W przeciwieństwie do tego,
Array<T>
nie ma konstruktora, który przyjmuje tylko parametr rozmiaru: potrzebuje prawidłowych, niezerowychT
wystąpień we wszystkich indeksach, aby były w prawidłowym stanie po utworzeniu. W przypadkuNumber
typów może to być ustawienie domyślne0
, ale nie ma możliwości tworzenia domyślnych instancji dowolnego typuT
.Tak więc podczas tworzenia
Array<Int>
możesz użyć konstruktora, który również przyjmuje funkcję inicjalizującą:val arr = Array<Int>(10) { index -> 0 } // full, verbose syntax val arr = Array(10) { 0 } // concise version
Lub utwórz ankietę,
Array<Int?>
aby uniknąć konieczności inicjowania każdej wartości, ale później będziesz zmuszony radzić sobie z możliwyminull
wartościami za każdym razem, gdy czytasz z tablicy.val arr = arrayOfNulls<Int>(10)
źródło
int[]
jestIntArray
,Integer[]
jestArray<Int>
i tak dalej, gdzie jest ta tajemnicza nowa klasa? To ta sama rzecz, tylko składnia jest inna.int[]
Nawiasem mówiąc, to także klasa.Warto zauważyć, że użycie
*
operatora spread ( ) na avararg
zwróciIntArray
. Jeśli potrzebujeszArray<Int>
, możesz przekonwertować plikIntArray
using.toTypedArray()
.źródło
Tablice w Kotlinie są klasami (nie typami „specjalnymi”, takimi jak Java).
Stdlib Kotlina zapewnia klasy specjalnego przeznaczenia dla tablic prymitywnych JVM w celu poprawy integracji i wydajności języka Java.
Praktyczną zasadą jest użycie
Array<T>
z wyjątkiem sytuacji, gdy powoduje to problem podczas mieszania z istniejącym kodem Java lub powinno być wywoływane z klas Java. Dla przypomnienia, nigdy nie musiałem używaćIntArray
.Możesz sprawdzić dokumentację języka dotyczącą tej sprawy tutaj: https://kotlinlang.org/docs/reference/basic-types.html#arrays
źródło
Int
,Float
itp, ponieważ Kotlin nie posiada innego rodzaju naBoolean
lubboolean
. Pod względem tablic zakładałbym,Array<Int>
że różni się odIntArray
. Osobiście zawsze używałem tego ostatniego, ponieważ nigdy mi to nie przeszkadzało, ale może Kotlin ma dodatkową optymalizację, której nie jestem świadomy. Jeśli programujesz wyłącznie w kotlinie, nie widzę żadnego przypadku, w którym potrzebujesz jednego nad drugim, ale prymitywna tablica może nadal mieć swoje zalety.