Menu

Array di Golang: Panjang Tetap, Disalin sebagai Nilai, vs Slice

Array di Go punya panjang tetap yang menjadi bagian dari tipenya, dan array disalin saat di-assign. Pelajari cara mendeklarasikan, menelusuri, membandingkan, dan mengirim array, serta kenapa kebanyakan kode Go memakai slice.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Mendeklarasikan array

Tipe array ditulis [N]T: panjang, lalu tipe elemen. Panjangnya sudah tetap saat kompilasi dan menjadi bagian dari tipe.

Output:

[90 0 0 0 75] 5
Tue
[5]int [2 3 5 7 11]
["" "b" "" "d" ""]

Array selalu terinisialisasi penuh. Elemen yang tidak kamu isi berisi zero value dari tipe elemennya: 0, "", false, nil.

Indeks dan batas

Indeks berjalan dari 0 sampai len(a)-1. Indeks konstanta di luar jangkauan adalah error kompilasi. Indeks berupa variabel yang di luar jangkauan akan panic saat program berjalan.

var a [3]int
a[5] = 1 // compile error: invalid argument: index 5 out of bounds [0:3]

i := 5
a[i] = 1 // panic: runtime error: index out of range [5] with length 3

Menelusuri array

for i, v := range a mengunjungi setiap elemen secara berurutan. v adalah salinan elemen, jadi mengubah v tidak mengubah array. Ubah lewat indeksnya.

Ada satu kehalusan lagi yang khusus untuk array: range atas nilai array mengevaluasi salinan array di awal. Kalau badan perulangan mengubah elemen berikutnya, v tetap menunjukkan nilai lama. Melakukan range atas &a atau a[:] menghindari salinan itu.

Array adalah nilai

Inilah perbedaan utama dengan array di C, Java, atau JavaScript. Meng-assign array menyalin setiap elemennya. Mengirim array ke fungsi juga menyalinnya.

Output:

[1 2 3] [99 2 3]
[1 2 3]
[0 2 3]

Menyalin itu murah untuk array kecil dan mahal untuk array besar: mengirim [1_000_000]int sebagai nilai menyalin delapan megabyte. Kirim pointer (*[N]T) atau slice (a[:]) kalau array-nya besar atau fungsinya perlu mengubah isinya. Mengakses indeks lewat pointer array tidak butuh * eksplisit: a[0] bisa dipakai pada *[3]int.

Membandingkan array dan memakainya sebagai key map

Array berisi elemen yang bisa dibandingkan mendukung == dan !=. Dua array sama jika setiap elemennya sama. Itu juga membuat array sah sebagai key map, sesuatu yang tidak bisa dilakukan slice.

Array dengan panjang berbeda adalah tipe yang berbeda dan sama sekali tidak bisa dibandingkan: [3]int{} == [4]int{} tidak bisa dikompilasi (mismatched types [3]int and [4]int).

Array multidimensi

Array berisi array memberimu grid berukuran tetap. Seluruh grid adalah satu blok memori yang bersambung.

row[:] mengubah baris [3]rune menjadi slice []rune, yang diterima oleh string().

Array vs slice

Array [N]TSlice []T
Panjangtetap, bagian dari tipeberubah dengan append
Assignment dan pengiriman ke fungsimenyalin semua elemenmenyalin header kecil, elemennya dipakai bersama
Zero valueN elemen bernilai nolnil, panjang 0
==ya, elemen demi elemenhanya terhadap nil
Key mapyatidak
Kegunaan umumdata berukuran tetap: hash, koordinat, bufferhampir semua hal lainnya

Dalam praktik, kamu akan lebih sering menemui array di beberapa tempat saja: sha256.Sum256 mengembalikan [32]byte, tabel lookup yang ukurannya tidak pernah berubah, dan sebagai tempat penyimpanan di balik sebuah slice. Memotong array dengan a[:] atau a[1:3] membuat slice yang memakai memori yang sama; halaman slice menjelaskan arti berbagi memori itu.

Konversi antara array dan slice

Mengonversi slice ke array (Go 1.20) atau ke pointer array (Go 1.17) akan panic jika slice lebih pendek dari panjang array: panic: runtime error: cannot convert slice with length 2 to array or pointer to array with length 3.

Kesalahan umum

  • Berharap fungsi mengubah argumen array. Fungsi itu menerima salinan. Kirim *[N]T atau slice.
  • Memakai array di tempat yang butuh slice. []int{1, 2} adalah slice, [2]int{1, 2} adalah array. Fungsi yang menerima []int tidak akan menerima [2]int; kirim a[:].
  • Array besar di perulangan range. for _, v := range bigArray menyalin seluruh array lebih dulu. Lakukan range atas &bigArray atau sebuah slice.

Pertanyaan yang sering diajukan

Bagaimana cara mendeklarasikan array di Go?

Tulis panjangnya di dalam kurung siku sebelum tipe elemen: var a [5]int membuat lima angka nol. Dengan nilai: a := [3]string{"x", "y", "z"}. Pakai [...] agar compiler yang menghitung: a := [...]int{1, 2, 3} bertipe [3]int.

Apa bedanya array dan slice di Go?

Array punya panjang tetap yang menjadi bagian dari tipenya ([3]int dan [4]int adalah tipe yang berbeda) dan disalin saat di-assign atau dikirim ke fungsi. Slice ([]int) adalah tampilan ke sebuah array di baliknya, dengan panjang yang bisa berubah lewat append, dan menyalin slice hanya menyalin tampilannya, bukan elemennya. Kebanyakan kode Go memakai slice.

Bagaimana cara mengetahui panjang array di Go?

Pakai fungsi bawaan len(a). Untuk array, nilainya adalah konstanta yang sudah diketahui saat kompilasi, jadi kamu bisa memakainya di ekspresi konstanta. cap(a) mengembalikan angka yang sama.

Apakah array bisa dibandingkan di Go?

Bisa, dengan == dan !=, asalkan tipe elemennya bisa dibandingkan. Dua array sama jika semua elemennya sama. Array juga bisa dipakai sebagai key map. Slice tidak bisa dibandingkan dengan == (kecuali dengan nil); untuk slice, pakai slices.Equal.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai