Senior
How is a slice in Go structured? Tell about its internal implementation, pitfalls, and nuances.
sobes.tech AI
Answer from AI
A slice in Go is a structure that describes a contiguous fragment of an array. Internally, a slice contains three fields:
- ptr — a pointer to the first element of the array that the slice refers to (not necessarily the first element of the entire array, but the first element of the slice);
- len — the length of the slice (number of elements);
- cap — the capacity of the slice (the maximum number of elements it can hold starting from ptr).
type sliceHeader struct {
ptr *ElementType
len int
cap int
}
Nuances and pitfalls:
- When creating a slice from an array or another slice, the new slice references the same underlying array. Changes through one slice are reflected in the other.
- If the slice is extended in length (via append), and the capacity is insufficient, a new array is created, and data is copied there.
- Due to shared use of the array, memory leaks can occur: if a slice refers to a large array but only a small part is used, the entire array will not be freed.
- When passing a slice to a function, the slice structure (ptr, len, cap) is copied, but the array data is not.
Example:
arr := [5]int{1,2,3,4,5}
s1 := arr[1:3] // slice with elements {2,3}
s2 := s1[:4] // extend length to 4, but not beyond cap
s2[3] = 10 // change element in the original array
fmt.Println(arr) // [1 2 3 10 5]
It is important to understand that slices are a convenient and efficient way to work with sequences, but you need to carefully monitor their capacity and the lifetime of the underlying array to avoid unexpected errors and memory leaks.