Array, slice, dan map sama-sama menampung banyak nilai, tetapi ketiganya dirancang untuk masalah yang berbeda. Memilih struktur yang tepat menentukan kecepatan program, keringkasan kode, dan kebebasan dari bug halus seperti aliasing. Kabar baiknya: setelah menempuh sembilan chapter sebelumnya, kita sudah punya semua pengetahuan untuk mengambil keputusan itu secara sadar. Chapter penutup ini merangkum ketiga struktur dalam satu tabel keputusan lalu mempraktikkan tiga skenario pilihan yang paling sering dijumpai.
Tabel Perbandingan #
| Aspek | Array | Slice | Map |
|---|---|---|---|
| Ukuran | Tetap, ditentukan saat kompilasi | Dinamis, tumbuh lewat append | Dinamis, tumbuh per key baru |
| Cara akses | a[i] lewat indeks | s[i] lewat indeks | m[k] lewat key comparable |
| Ordo akses | Konstan | Konstan | Rata-rata konstan |
| Iterasi terurut | Ya, dari indeks 0 | Ya, dari indeks 0 | Tidak; key harus diurutkan dulu |
| Urutan penyimpanan | Terjaga | Terjaga | Tidak terjaga |
| Salinan saat assignment | Seluruh isi disalin | Hanya header slice yang disalin | Hanya penunjuk map yang disalin |
| Use case khas | Buffer tetap, RGB, hash | Daftar berurutan, riwayat, antrean | Kamus, indeks, penghitungan frekuensi |
Tiga baris teratas adalah kriteria utama: tanyakan apakah ukuran data tetap, apakah akses dilakukan lewat posisi atau lewat key, dan apakah urutan perlu terjaga. Jawaban atas ketiganya hampir selalu langsung menunjuk satu struktur.
Daftar Berurutan: Pilih Slice #
Ketika urutan penulisan data bermakna — langkah proses, riwayat pesanan, antrean tugas — slice adalah pilihan default. Urutan elemen slice terjaga sejak awal, indeks memungkinkan akses konstan ke posisi mana pun, dan append menampung pertumbuhan data tanpa biaya desain. Konsekuensinya: mencari satu nilai tertentu di slice memeriksa elemen satu per satu, sehingga makin panjang slice makin lama pencarian. Bila pencarian seperti itu menjadi frekuensi utama program, itu pertanda struktur yang dibutuhkan bukan slice.
Lookup Berdasarkan Key: Pilih Map #
Ketika data diakses lewat nama, kode, atau identitas lain — bukan posisi — map menjawab langsung: kodePos["Bandung"] menemukan nilai tanpa memeriksa entri lain. Map juga unggul saat menghitung frekuensi kemunculan, misalnya frekuensi[kata]++ yang bekerja meski key belum pernah ada. Imbalannya, urutan penyimpanan tidak dijaga dan iterasi harus diurutkan secara eksplisit memakai slices.Sorted(maps.Keys(m)) bila output perlu stabil.
Ukuran Selalu Tetap: Pilih Array #
Array layak dipilih ketika ukuran data memang tidak mungkin berubah: warna piksel selalu tiga byte, hash SHA-256 selalu 32 byte, buffer I/O berukuran tetap. Nilai yang disalin utuh saat assignment juga menjadi keuntungan tersendiri: array bebas dari bug aliasing yang menghantui slice. Untuk semua kasus lain — hampir seluruh kode sehari-hari — slice dan map lebih luwes.
Program Utuh #
Berkas pilihan-demo.go menerapkan ketiga keputusan dalam satu program. Jalankan dengan go run pilihan-demo.go dari direktori chapter:
package main
import (
"fmt"
"maps"
"slices"
)
func main() {
// Daftar berurutan: urutan penulisan harus terjaga, pakai slice.
urutan := []string{"masuk", "pilih barang", "checkout"}
fmt.Println("urutan:", urutan)
// Cari nilai di slice: periksa elemen satu per satu.
target := "checkout"
ditemukan := false
for _, langkah := range urutan {
if langkah == target {
ditemukan = true
break
}
}
fmt.Println("checkout ditemukan:", ditemukan)
// Lookup berdasarkan key: akses langsung, pakai map.
kodePos := map[string]int{
"Jakarta Pusat": 10110,
"Bandung": 40111,
"Surabaya": 60119,
}
if kp, ok := kodePos["Bandung"]; ok {
fmt.Println("kode pos Bandung:", kp)
}
// Iterasi map yang terurut memakai slices dan maps.
for _, kota := range slices.Sorted(maps.Keys(kodePos)) {
fmt.Printf("%s: %d\n", kota, kodePos[kota])
}
// Data berukuran tetap: warna RGB selalu tiga byte, pakai array.
piksel := [3]byte{255, 128, 0}
fmt.Println("piksel:", piksel)
}Output yang Dihasilkan:
urutan: [masuk pilih barang checkout]
checkout ditemukan: true
kode pos Bandung: 40111
Bandung: 40111
Jakarta Pusat: 10110
Surabaya: 60119
piksel: [255 128 0]Mari kita telaah baris demi baris program di atas:
- Baris 11 (
urutan := []string{...}): langkah proses disimpan sebagai slice karena urutan masuk-pilih-checkout adalah bagian dari makna data. - Baris 14–22 (loop pencarian): menemukan
"checkout"menuntut pemeriksaan elemen satu per satu denganbreak— karakteristik pencarian di slice yang perlu dipertimbangkan saat memilih struktur. - Baris 25–30 (map
kodePos): pencarian kode pos dilakukan lewat key; comma-ok memastikan key ada sebelum nilainya dipakai. - Baris 33–35 (
slices.Sorted(maps.Keys(kodePos))): iterasi terurut menghasilkan output Bandung, Jakarta Pusat, Surabaya yang stabil di setiap eksekusi. - Baris 38 (
piksel := [3]byte{255, 128, 0}): warna piksel berukuran pasti tiga byte sehingga array[3]bytepas — tidak ada kemungkinan tumbuh yang justru tidak diinginkan.
Ketiga struktur ini akan terus muncul di sepanjang perjalanan kita, mulai dari pengolahan string di Section String dan Text Processing
hingga struktur data concurrency. Dengan tabel keputusan di atas, setiap kali mendeklarasikan []T atau map[K]V, kita melakukannya karena sadar itu pilihan paling tepat — bukan sekadar kebiasaan.
Referensi #
- Go Blog: Arrays, slices (and strings): The mechanics of append — ringkasan desain array dan slice.
- Go Blog: Maps in action (maps) — panduan pemakaian map.
- Dokumentasi package slices — utilitas slice modern.
- A Tour of Go: More types — latihan interaktif ketiga struktur.
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
pilihan-demo.go
Unduh berkaspackage main
import (
"fmt"
"maps"
"slices"
)
func main() {
// Daftar berurutan: urutan penulisan harus terjaga, pakai slice.
urutan := []string{"masuk", "pilih barang", "checkout"}
fmt.Println("urutan:", urutan)
// Cari nilai di slice: periksa elemen satu per satu.
target := "checkout"
ditemukan := false
for _, langkah := range urutan {
if langkah == target {
ditemukan = true
break
}
}
fmt.Println("checkout ditemukan:", ditemukan)
// Lookup berdasarkan key: akses langsung, pakai map.
kodePos := map[string]int{
"Jakarta Pusat": 10110,
"Bandung": 40111,
"Surabaya": 60119,
}
if kp, ok := kodePos["Bandung"]; ok {
fmt.Println("kode pos Bandung:", kp)
}
// Iterasi map yang terurut memakai slices dan maps.
for _, kota := range slices.Sorted(maps.Keys(kodePos)) {
fmt.Printf("%s: %d\n", kota, kodePos[kota])
}
// Data berukuran tetap: warna RGB selalu tiga byte, pakai array.
piksel := [3]byte{255, 128, 0}
fmt.Println("piksel:", piksel)
}