I read go slice usage and internals and Slice and Effective go#slice but there is nothing about slicing a slice with 3 number like this : slice[a:b:c]
For example this code :
package main
import "fmt"
func main() {
var s = []string{"a", "b", "c", "d", "e", "f", "g"}
fmt.Println(s[1:2:6], len(s[1:2:6]), cap(s[1:2:6]))
fmt.Println(s[1:2:5], len(s[1:2:5]), cap(s[1:2:5]))
fmt.Println(s[1:2], len(s[1:2]), cap(s[1:2]))
}
go playground result is this :
[b] 1 5
[b] 1 4
[b] 1 6
I can understand that the third one is something about capacity, but what is the exact meaning of this?
Do I miss something in documents?
The syntax has been introduced in Go 1.2, as I mentioned in "Re-slicing slices in Golang".
It is documented in Full slice expressions:
a[low : high : max]
constructs a slice of the same type, and with the same length and elements as the simple slice expression
a[low : high]
.
Additionally, it controls the resulting slice's capacity by setting it tomax - low
.
Only the first index may be omitted; it defaults to 0.After slicing the array
a
:a := [5]int{1, 2, 3, 4, 5} t := a[1:3:5]
the slice t has type []int, length 2, capacity 4, and elements
t[0] == 2 t[1] == 3
The design document for that feature had the following justification:
It would occasionally be useful, for example in custom
[]byte
allocation managers, to be able to hand a slice to a caller and know that the caller cannot edit values beyond a given subrange of the true array.The addition of
append
to the language made this somewhat more important, becauseappend
lets programmers overwrite entries betweenlen
andcap
without realizing it or even mentioningcap
.
2022: endvvell adds for Go 1.19+:
while the capacity of a "derivative" slice doesn't exceed the one specified by the third index during its creation the slice is still "from" the same spot in the memory as its original ("true") slice, so the changes applied to it will affect the original slice.
And if then, for example, you append to this derivative slice the amount of elements that would cause its capacity to be increased, this new slice will occupy a different place in the memory, and so the changes made to it will not affect the slice it originated from.