Program yang kita tulis sejauh ini menyimpan satu nilai di dalam satu variabel. Begitu data yang harus ditampung bertambah banyak, kita membutuhkan wadah untuk kumpulan nilai. Array adalah wadah paling dasar di Go: deretan elemen bertipe sama dengan jumlah slot yang tetap sejak dideklarasikan. Meskipun array jarang dipakai secara langsung di kode sehari-hari, array menjadi fondasi bagi slice yang kita bahas pada chapter-chapter berikutnya, sehingga memahami perilaku array membuat materi selanjutnya jauh lebih mudah dicerna.
Mendeklarasikan Array #
Tipe array ditulis dengan bentuk [n]T, yang berarti array memiliki n slot untuk nilai bertipe T. Nilai n harus berupa bilangan non-negatif yang sudah diketahui saat kompilasi, dan jumlah slot tersebut tidak dapat berubah setelah array dibuat. Tiga bentuk deklarasi yang paling sering kita jumpai:
var skor [3]int // zero value: [0 0 0]
angka := [3]int{10, 20, 30} // literal dengan nilai awal
warna := [3]string{"merah", "hijau", "biru"}Array yang dideklarasikan tanpa nilai awal langsung siap dipakai karena setiap slot otomatis terisi zero value tipe elemennya: [3]int berisi [0 0 0], sedangkan [3]string berisi tiga string kosong. Elemen diakses dengan indeks yang dimulai dari nol, misalnya angka[1] untuk membaca elemen kedua, dan jumlah slot dibaca dengan len(angka). Membaca indeks di luar jangkauan seperti angka[5] pada array [3]int memicu runtime panic; kompilator tidak memeriksa galat ini saat program dibangun.
Panjang adalah Bagian dari Tipe #
Go memperlakukan panjang sebagai bagian dari tipe array. Akibatnya [3]int dan [4]int adalah dua tipe yang berbeda dan tidak dapat saling dioperasikan. Program berikut gagal dikompilasi:
var a [3]int = [3]int{1, 2, 3}
var b [4]int
b = a // galat: tipe tidak cocokKompilator menolak baris terakhir dengan pesan cannot use a (variable of type [3]int) as [4]int value in assignment. Kegagalan ini terjadi saat kompilasi, bukan saat program berjalan, sehingga ketidakcocokan panjang tertangkap sejak awal. Sifat yang sama juga berlaku untuk parameter fungsi: fungsi bertanda func proses(data [3]int) hanya menerima array berpanjang tepat tiga dan menolak [4]int.
Array Adalah Nilai, Bukan Referensi #
Perbedaan paling penting array Go dibanding banyak bahasa pemrograman lain: array adalah nilai utuh. Assignment dan pemanggilan fungsi menyalin seluruh isi array, bukan sekadar menyimpan alamatnya. Berkas array-demo.go berikut membuktikan perilaku salinan tersebut melalui tiga eksperimen: assignment, modifikasi hasil salinan, dan pemanggilan fungsi.
package main
import "fmt"
// ubahIsi menerima salinan array, mengubah salinan tersebut, lalu mengembalikannya.
func ubahIsi(arr [3]int) [3]int {
arr[0] = 999
return arr
}
func main() {
// Deklarasi tanpa nilai awal: zero value untuk setiap elemen.
var kosong [3]int
fmt.Println("kosong :", kosong)
// Literal array: panjang ditulis di dalam tipe.
angka := [3]int{10, 20, 30}
fmt.Println("angka :", angka)
fmt.Println("len :", len(angka))
// Assignment menyalin seluruh isi array.
salinan := angka
salinan[0] = 1000
fmt.Println("salinan:", salinan)
fmt.Println("angka :", angka)
// Array yang dilewatkan ke fungsi juga ikut disalin.
hasil := ubahIsi(angka)
fmt.Println("hasil :", hasil)
fmt.Println("angka :", angka)
}Output yang Dihasilkan:
kosong : [0 0 0]
angka : [10 20 30]
len : 3
salinan: [1000 20 30]
angka : [10 20 30]
hasil : [999 20 30]
angka : [10 20 30]Mari kita telaah baris demi baris program di atas:
- Baris 6 (
func ubahIsi(arr [3]int) [3]int): parameterarrbertipe[3]int. Setiap pemanggilan menyalin seluruh isi array ke parameter, sehingga perubahan di dalam fungsi hanya menyangkut salinan. - Baris 13 (
var kosong [3]int): mendeklarasikan array tanpa nilai awal sehingga ketiga slot terisi zero value0, terbukti dari output[0 0 0]. - Baris 17 (
angka := [3]int{10, 20, 30}): membuat array tiga elemen dengan literal;len(angka)menghasilkan3. - Baris 22–23 (
salinan := angka; salinan[0] = 1000): assignment menyalin seluruh isi, lalu penulisansalinan[0]hanya mengubah salinan. - Baris 24–25: bukti salinan —
salinantercetak[1000 20 30]sementaraangkatetap[10 20 30]. - Baris 28–30 (
hasil := ubahIsi(angka)): fungsi mengembalikan salinan yang sudah diubah ([999 20 30]), sedangkanangkadimaintetap utuh karena parameter yang dimodifikasi hanyalah salinan.
Mengapa Array Jarang Dipakai Langsung #
Sifat tetap dari panjang array menjadi kendala utama di program nyata: jumlah data umumnya baru diketahui saat program berjalan, sementara n harus ditentukan saat kompilasi. Salinan menyeluruh pada assignment dan parameter juga menambah biaya untuk array berukuran besar. Karena itulah kode Go sehari-hari hampir selalu memakai slice, struktur yang dibangun di atas array dan dapat tumbuh secara dinamis; kita akan membahas slice segera pada chapter berikutnya.
Referensi #
- Go Blog: Arrays, slices (and strings): The mechanics of append — penjelasan resmi array sebagai fondasi slice.
- A Tour of Go: More types — tur resmi struct, array, slice, dan map.
Pada chapter berikutnya kita meninggalkan kaku ukuran tetap dan berkenalan dengan slice, struktur data yang paling sering dipakai di Go untuk menampung kumpulan nilai.
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
array-demo.go
Unduh berkaspackage main
import "fmt"
// ubahIsi menerima salinan array, mengubah salinan tersebut, lalu mengembalikannya.
func ubahIsi(arr [3]int) [3]int {
arr[0] = 999
return arr
}
func main() {
// Deklarasi tanpa nilai awal: zero value untuk setiap elemen.
var kosong [3]int
fmt.Println("kosong :", kosong)
// Literal array: panjang ditulis di dalam tipe.
angka := [3]int{10, 20, 30}
fmt.Println("angka :", angka)
fmt.Println("len :", len(angka))
// Assignment menyalin seluruh isi array.
salinan := angka
salinan[0] = 1000
fmt.Println("salinan:", salinan)
fmt.Println("angka :", angka)
// Array yang dilewatkan ke fungsi juga ikut disalin.
hasil := ubahIsi(angka)
fmt.Println("hasil :", hasil)
fmt.Println("angka :", angka)
}