Be careful of shared array
In Go, when you take a slice of an existing slice, you get two slices sharing the same underlying array.
package main
import "fmt"
func main() {
s1 := []int{1, 2, 3}
// A slice of s1 => {2, 3}
s2 := s1[1:3]
// The 0th element of s2 is the 1th element of s1
s2[0] = 42
fmt.Println(s1) // [1 42 3]
fmt.Println(s2) // [42 3]
}
And we can append items to slices with the built-in function append
.
package main
import "fmt"
func main() {
s1 := []int{1, 2, 3}
// A slice of s1 => {2}
s2 := s1[1:2]
s2 = append(s2, 42)
fmt.Println(s1) // [1 2 42]
fmt.Println(s2) // [2 42]
}
Buf if there’s not available capacity for appending new items, append
would create a new bigger underlying array for you, and the returned slice will point to this new array.
package main
import "fmt"
func main() {
s1 := []int{1, 2, 3}
// Create a slice of s1 => {2, 3}
// The len of s2 would be 2, and the capacity would also be 2
// Which is to say, s2 is full
s2 := s1[1:3]
// Not available capacity for the new item
// `append` helps us replace the underlying array with a bigger one
s2 = append(s2, 42)
// Now that the underlying array for s2 is a different one
// updating an item of s2 would have no effect on s1
s2[0] = 11
fmt.Println(s1) // [1 2 3]
fmt.Println(s2) // [11 3 42]
}
So we need to be careful, two related slices may independently grow and change their underlying array.