Chapter 5 of 10
Setelah bab ini, Anda mampu:
append, dan copy;comma-ok.Array menyimpan elemen berjumlah tetap. Panjangnya menjadi bagian dari tipe; [3]int berbeda dari [4]int.
package main
import "fmt"
func main() {
var nol [3]int
prima := [4]int{2, 3, 5, 7}
otomatis := [...]string{"merah", "hijau", "biru"}
fmt.Println(nol, prima, otomatis)
fmt.Println(len(prima), prima[0])
}
Assignment dan parameter array menyalin seluruh array. Array berguna untuk ukuran intrinsik dan tetap, misalnya hash 32 byte. Untuk koleksi umum, slice lebih fleksibel.
Slice bukan array. Slice adalah descriptor yang mereferensikan segmen backing array, dengan panjang (len) dan kapasitas (cap).
package main
import "fmt"
func main() {
angka := []int{10, 20, 30, 40, 50}
bagian := angka[1:4]
fmt.Println(bagian, len(bagian), cap(bagian))
bagian[0] = 99
fmt.Println(angka)
}
Batas a[low:high] mencakup low dan tidak mencakup high. Kapasitas dihitung dari awal slice sampai akhir backing array yang tersedia.
Buat slice dengan make ketika panjang atau kapasitas diketahui:
package main
import "fmt"
func main() {
a := make([]int, 3)
b := make([]int, 0, 8)
fmt.Println(a, len(a), cap(a))
fmt.Println(b, len(b), cap(b))
}
make([]int, 3) menghasilkan tiga elemen yang sudah dapat diindeks. make([]int, 0, 8) belum memiliki elemen, sehingga b[0] panic; kapasitas bukan panjang.
append, Kapasitas, dan Aliasappend mengembalikan slice baru dan hasilnya harus disimpan. Jika kapasitas cukup, backing array lama dapat dipakai; jika tidak, runtime mengalokasikan array baru.
package main
import "fmt"
func main() {
nilai := make([]int, 0, 2)
nilai = append(nilai, 10, 20)
nilai = append(nilai, 30)
fmt.Println(nilai, len(nilai), cap(nilai))
}
Karena dua slice dapat berbagi backing array, perubahan atau append kadang terlihat melalui slice lain dan kadang tidak setelah realokasi. Jangan bergantung pada detail pertumbuhan kapasitas.
Gunakan full slice expression untuk membatasi kapasitas saat perlu mencegah append menimpa bagian lain:
semua := []int{1, 2, 3, 4}
kiri := semua[:2:2]
kiri = append(kiri, 9)
fmt.Println(semua, kiri)
Kapasitas kiri dibatasi dua, sehingga append memerlukan backing array baru.
Assignment slice menyalin header, bukan elemen. Untuk salinan independen, gunakan copy atau append ke slice baru.
package main
import "fmt"
func main() {
asal := []int{1, 2, 3}
salinan := make([]int, len(asal))
copy(salinan, asal)
salinan[0] = 99
fmt.Println(asal, salinan)
}
copy(dst, src) mengembalikan jumlah elemen yang disalin, yaitu minimum panjang keduanya.
var nilSlice []int
emptySlice := []int{}
madeEmpty := make([]int, 0)
Ketiganya memiliki panjang nol dan aman untuk range serta append. Hanya nilSlice == nil yang benar. Perbedaan dapat tampak pada serialisasi atau API eksternal (null versus []), sehingga ikuti kontrak boundary. Slice tidak dapat dibandingkan dengan slice lain; hanya dapat dibandingkan dengan nil.
comma-okMap menyimpan pasangan key-value. Key harus comparable; slice, map, dan function tidak dapat menjadi key.
package main
import "fmt"
func main() {
skor := map[string]int{
"Ayu": 90,
"Bima": 82,
}
skor["Citra"] = 88
nilai, ada := skor["Ayu"]
fmt.Println(nilai, ada)
hapusNilai, ada := skor["Doni"]
fmt.Println(hapusNilai, ada)
delete(skor, "Bima")
fmt.Println(len(skor))
}
Lookup key yang tidak ada menghasilkan zero value. Karena zero value mungkin nilai valid, gunakan bentuk nilai, ada := m[key] untuk membedakannya.
Map nil dapat dibaca dan menghasilkan zero value, tetapi penulisan menyebabkan panic:
var m map[string]int
fmt.Println(m["x"])
m = make(map[string]int)
m["x"] = 1
Map adalah reference-like descriptor. Assignment atau pengiriman ke fungsi membuat descriptor baru yang mengacu data map sama. Map tidak aman untuk read/write bersamaan tanpa sinkronisasi. Urutan iterasinya tidak ditentukan.
Pola penghitung:
package main
import "fmt"
func main() {
frekuensi := make(map[rune]int)
for _, r := range "banana" {
frekuensi[r]++
}
fmt.Println(frekuensi['a'])
}
Zero value int membuat increment langsung bekerja tanpa pemeriksaan keberadaan.
len.append. Tulis s = append(s, x).copy untuk independensi.make.comma-ok.nil.len/cap setelah setiap append.copy.map[string]int.bool, termasuk kasus nomor kosong sebagai nilai valid.len, range, append, dan pemeriksaan == nil.Array memiliki ukuran tetap yang menjadi bagian tipe. Slice menyediakan tampilan fleksibel ke backing array melalui pointer, panjang, dan kapasitas; append dapat mempertahankan atau mengganti storage, sedangkan copy membuat elemen independen. Map memberi lookup efisien tetapi tidak menjamin urutan. Pahami nilai nil, aliasing, batas indeks, dan pola comma-ok agar pengelolaan koleksi tetap benar.