Cap and Length in Go Slice
original := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
// original: len=10, cap=10
slice1 := original[2:6] // [3,4,5,6]
// slice1: len=4, cap=8 (karena mulai dari index 2, sisa capacity = 10-2 = 8)
slice2 := slice1[1:4] // [4,5,6]
// slice2: len=3, cap=7 (ini yang menjadi pertanyaan)
Mengapa Capacity = 7?
Kunci pemahamannya: Capacity dihitung dari pointer awal slice sampai akhir array underlying.
Array Underlying:
[1,2,3,4,5,6,7,8,9,10]
(capacity = 10)Slice1 (
original[2:6]
):Pointer: index 2 (nilai 3)
Length: 4 elemen (index 2-5: [3,4,5,6])
Capacity: 8 (dari index 2 sampai akhir array: 10-2 = 8)
Slice2 (
slice1[1:4]
):Pointer: index 1 dari slice1 (yang sebenarnya index 3 dari array underlying)
Length: 3 elemen ([4,5,6])
Capacity: 7 (dari index 3 sampai akhir array: 10-3 = 7)
Visualisasi
Array Underlying: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Indeks: 0 1 2 3 4 5 6 7 8 9
original: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
β β β β β β β β β β
seluruh array (cap=10)
slice1: original[2:6] β [3,4,5,6]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
β β β β
slice1 (len=4, cap=8)
Pointer di index 2, sisa capacity sampai index 9 = 8
slice2: slice1[1:4] β [4,5,6]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
β β β
slice2 (len=3, cap=7)
Pointer di index 3, sisa capacity sampai index 9 = 7
Contoh Kode untuk Memperjelas
package main
import "fmt"
func main() {
original := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
fmt.Printf("Original: %v, len: %d, cap: %d\n", original, len(original), cap(original))
slice1 := original[2:6] // [3,4,5,6]
fmt.Printf("slice1 (original[2:6]): %v\n", slice1)
fmt.Printf(" Pointer menunjuk ke: %d (index 2 dari original)\n", original[2])
fmt.Printf(" len: %d, cap: %d (10 - 2 = 8)\n", len(slice1), cap(slice1))
slice2 := slice1[1:4] // [4,5,6]
fmt.Printf("slice2 (slice1[1:4]): %v\n", slice2)
fmt.Printf(" Pointer menunjuk ke: %d (index 3 dari original)\n", original[3])
fmt.Printf(" len: %d, cap: %d (10 - 3 = 7)\n", len(slice2), cap(slice2))
// Bukti bahwa mereka share array yang sama
fmt.Println("\n=== Membuktikan Shared Array ===")
slice2[0] = 999 // Ubah element pertama slice2
fmt.Printf("Setelah ubah slice2[0] = 999:\n")
fmt.Printf("slice2: %v\n", slice2)
fmt.Printf("slice1: %v\n", slice1)
fmt.Printf("original: %v\n", original)
}
Output:
Original: [1 2 3 4 5 6 7 8 9 10], len: 10, cap: 10
slice1 (original[2:6]): [3 4 5 6]
Pointer menunjuk ke: 3 (index 2 dari original)
len: 4, cap: 8 (10 - 2 = 8)
slice2 (slice1[1:4]): [4 5 6]
Pointer menunjuk ke: 4 (index 3 dari original)
len: 3, cap: 7 (10 - 3 = 7)
=== Membuktikan Shared Array ===
Setelah ubah slice2[0] = 999:
slice2: [999 5 6]
slice1: [3 999 5 6]
original: [1 2 3 999 5 6 7 8 9 10]
Rumus Umum Capacity
Untuk slice original[start:end]
:
Length =
end - start
Capacity =
cap(original) - start
Jadi dalam kasus ini:
slice1 = original[2:6]
β cap = 10 - 2 = 8slice2 = slice1[1:4]
β slice1 punya cap = 8, start = 1Tapi ingat!
slice1[1]
sebenarnya adalahoriginal[3]
Jadi cap(slice2) = cap(original) - 3 = 10 - 3 = 7
Inilah mengapa capacity menjadi 7 - karena dihitung dari pointer awal slice terhadap array underlying, bukan dari slice parent-nya.
Last updated