What is the full slice expression a[low:high:max], and when would you use it?
Question 44MediumGo 1.22 to 1.25
a[low:high:max] makes a slice with len = high-low and cap = max-low. The constraint is 0 <= low <= high <= max <= cap(a). A plain a[low:high] keeps all the capacity up to the end of the backing array. That means an append on the subslice silently overwrites the parent's elements.
s := []int{1, 2, 3, 4, 5}
s2 := s[1:3]
fmt.Println(len(s2), cap(s2)) // 2 4
s2 = append(s2, 10)
fmt.Println(s) // [1 2 3 10 5] -- s[3] was clobbered
s = []int{1, 2, 3, 4, 5}
s3 := s[1:3:3] // cap limited to 2
s3 = append(s3, 10) // forces reallocation
fmt.Println(s, s3) // [1 2 3 4 5] [2 3 10]
Use cases:
- Returning a subslice of an internal buffer when callers may append to it.
- Splitting one allocation into several independent chunks.
- The idiom
append(s[:len(s):len(s)], x)to get a guaranteed copy-on-append.
The standard library does this too, for example in bytes.Split results. Note: strings support only the two-index form.
More on Arrays, Slices, Maps & Strings
- Q42How does append grow a slice? Why is the resulting capacity sometimes not exactly double?
- Q43What does this print? (two appends on the same base slice)
- Q45What is the difference between a nil slice and an empty slice? When does it matter?
- Q46Explain the semantics of the built-in copy. Is it safe with overlapping slices?
- Q47How do arrays differ from slices? Can you convert between them?
- Q48What does this print? (range over an array vs a slice)