IntArray vs Array <Int> di Kotlin

91

Saya tidak yakin apa perbedaan antara an IntArraydan an Array<Int>di Kotlin dan mengapa saya tidak dapat menggunakannya secara bergantian:

missmatch

Saya tahu itu IntArrayditerjemahkan menjadi int[]ketika menargetkan JVM, tapi apa yang Array<Int>diterjemahkan ke?

Selain itu, Anda juga dapat memiliki String[]atau YourObject[]. Mengapa Kotlin memiliki kelas tipe {primitive}Arrayketika hampir semua hal dapat diatur ke dalam array, tidak hanya primitif.

FRR
sumber
1
Dugaan saya adalah bahwa Array<Int>mengkompilasi ke Integer[](jika kompiler tidak mengoptimalkan ini)
Mibac
Yup, itu sangat masuk akal, terima kasih keduanya!
FRR

Jawaban:

111

Array<Int>adalah di Integer[]bawah tenda, sedangkan IntArrayadalah int[]. Itu dia.

Ini berarti bahwa ketika Anda menempatkan Intdalam Array<Int>, itu akan selalu kotak (khusus, dengan Integer.valueOf()panggilan). Dalam kasus IntArray, tidak ada tinju yang akan terjadi, karena ini diterjemahkan ke array primitif Java.


Selain kemungkinan implikasi kinerja di atas, ada juga kemudahan untuk dipertimbangkan. Array primitif dapat dibiarkan tidak diinisialisasi dan akan memiliki 0nilai default di semua indeks. Inilah sebabnya mengapa IntArraydan array primitif lainnya memiliki konstruktor yang hanya mengambil parameter ukuran:

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

Sebaliknya, Array<T>tidak memiliki konstruktor yang hanya mengambil parameter ukuran: ia memerlukan Tinstance non-null yang valid di semua indeks agar berada dalam keadaan valid setelah dibuat. Untuk Numbertipe, ini bisa menjadi default 0, tetapi tidak ada cara untuk membuat contoh default dari tipe arbitrer T.

Jadi saat membuat Array<Int>, Anda bisa menggunakan konstruktor yang juga menggunakan fungsi penginisialisasi:

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

Atau buat Array<Int?>untuk menghindari keharusan menginisialisasi setiap nilai, tetapi kemudian Anda akan dipaksa untuk menangani kemungkinan nullnilai setiap kali Anda membaca dari array.

val arr = arrayOfNulls<Int>(10)
zsmb13
sumber
4
Ini keputusan yang cukup bodoh. Karena itu, mereka harus membuat kelas baru untuk setiap tipe primitif ... Mereka bisa menggunakan yang sama seperti di Java.
Pengembang android
1
@androiddeveloper Apa kelas baru? int[]adalah IntArray, Integer[]apakah Array<Int>, dan seterusnya, di mana kelas baru yang misterius ini? Itu hal yang sama hanya sintaks yang berbeda. int[]juga berkelas.
Eugen Pechanec
1
@EugenPechanec Ini menarik. Mereka mengatakan itu adalah kelas dan memiliki sebuah instance, tetapi juga "instance dari kelas ini direpresentasikan sebagai int []": kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int-array/… . Jadi, apakah fungsi-fungsi itu hanya fungsi ekstensi, atau apakah itu kelas nyata? Dan mengapa perlu memiliki "IntArray", dan lainnya? Masih bisa dilakukan menggunakan sintaks Java.
pengembang android
1
@EugenPechanec Tapi di Jawa, int [] bukan kelas, bukan? Itu sebuah objek, sebuah array primitif. Anda tidak dapat menjangkau adalah kode, atau memperluas darinya. Tidak? Semua kelas di Jawa memiliki huruf besar di namanya. Ini bukan.
Pengembang android
1
@EugenPechanec Jadi di Kotlin ini adalah sebuah kelas, sedangkan di Java tidak. Masih belum mengerti mengapa. Mereka hanya dapat menambahkan fungsi ekstensi, bukan? Anda mungkin dapat memperluas dari IntArray? Tentang penamaannya, saya tahu. Itu hanya konvensi, dan bagus juga.
Pengembang android
6

Perlu dicatat bahwa menggunakan *operator spread ( ) pada a varargakan mengembalikan file IntArray. Jika Anda membutuhkan Array<Int>, Anda dapat mengonversi IntArraypenggunaan .toTypedArray().

Eran Boudjnah
sumber
1

Array di Kotlin adalah kelas (bukan tipe "khusus" seperti Java).

Stdlib Kotlin menyediakan kelas tujuan khusus untuk array primitif JVM untuk meningkatkan integrasi dan kinerja bahasa Java.

Aturan praktisnya adalah menggunakan Array<T>kecuali jika menyebabkan masalah saat mencampur dengan kode Java yang ada, atau harus dipanggil dari kelas Java. Sebagai catatan, saya tidak pernah menggunakan IntArray.

Anda dapat memeriksa dokumentasi Bahasa terkait masalah ini di sini: https://kotlinlang.org/docs/reference/basic-types.html#arrays

jaguililla.dll
sumber
Saya percaya Anda benar tentang selalu menyukai Array <T> daripada IntArray, saya khawatir tentang overhead tinju / unboxing menggunakan tipe kotak vs primitif, tetapi tampaknya Kotlin cukup pintar untuk memutuskan cuaca dapat menggunakan primitif atau tidak . (Koreksi saya jika saya salah) "Pada platform Java, angka secara fisik disimpan sebagai tipe primitif JVM, kecuali kita memerlukan referensi nomor nullable (misalnya Int?) Atau generik yang terlibat. Dalam kasus terakhir, angka dikotakkan." Dari kotlinlang.org/docs/reference/basic-types.html
FRR
@feresr bukan ahli dengan cara apapun, tapi saya pikir itu hanya mengacu pada implementasi Int, Float, dll, mengingat bahwa Kotlin tidak memiliki tipe yang berbeda untuk Booleanatau boolean. Dalam hal array, saya akan berasumsi bahwa itu Array<Int>akan berbeda dari IntArray. Saya pribadi selalu menggunakan yang terakhir karena tidak pernah mengganggu saya, tetapi mungkin Kotlin memiliki pengoptimalan tambahan yang tidak saya sadari. Jika Anda memprogram hanya di kotlin, saya tidak melihat kasus apa pun di mana Anda membutuhkannya di atas yang lain, tetapi array primitif mungkin masih memiliki manfaatnya.
Allan W
@ AllanW juga bukan ahli, hanya penasaran, saya percaya java memiliki objek primitif dan kotak karena lebih efisien untuk bekerja dengan primitif bukan?, Tentu saja terkadang Anda benar-benar perlu bekerja dengan objek (nullability / generics). Ini keluar dari cakupan pertanyaan awal saya, tetapi saya bertanya-tanya bagaimana Kotlin menangani ini saat menargetkan JVM. Saya mencoba menggunakan IntArray bila memungkinkan (berpikir bahwa itu menggunakan primitif di bawah tenda) tetapi setelah @ komentar jamming saya tidak yakin lagi.
FRR
1
@feresr bagi saya, dokumen Kotlin secara eksplisit menyatakan bahwa instance array khusus ada untuk menghindari overhead tinju. Kesimpulan saya adalah bahwa keduanya mungkin berbeda, dan pada akhirnya bagi pengembang itu menjadi sama seperti memutuskan apakah Anda ingin menggunakan Integer [] atau int [] di Java.
Allan W
Saya setuju, maka jawaban yang diterima bisa sedikit menyesatkan bagi pendatang baru, saya tidak menandai ini sebagai jawaban yang diterima karena alasan ini.
FRR