Chapter 6 of 20
Arrays & Slices
Fixed arrays, slice internals, make/append/copy
Arrays
An array's length is part of its type — [3]int and [4]int are different types. Arrays are copied by value when passed, so real-world code rarely uses arrays directly.
package main
import "fmt"
func main() {
var a [3]int // [0 0 0]
b := [3]int{1, 2, 3}
c := [...]int{1, 2, 3} // compiler infers the length
fmt.Println(a, b, c, len(c))
}Slices
A slice is a reference to an underlying array, holding a pointer, a length, and a capacity. It can grow dynamically and is Go's most-used collection type.
package main
import "fmt"
func main() {
s := []int{1, 2, 3} // literal
s = append(s, 4, 5)
s2 := make([]int, 3, 10) // len=3, cap=10
fmt.Println(s, len(s), cap(s))
fmt.Println(s[1:3]) // sub-slice [2 3]
fmt.Println(s2)
}append and Growth
When cap is not enough, append allocates a new underlying array and copies into it. The return value must be reassigned to the original slice.
package main
import "fmt"
func main() {
s := []int{1, 2, 3}
s = append(s, 4) // must assign it back
fmt.Println(s, len(s), cap(s))
}copy and Shared Underlying Arrays
Sub-slices share the underlying array, so mutations affect one another. Use copy, or append onto a nil slice, to create an independent copy.
package main
import "fmt"
func main() {
src := []int{1, 2, 3}
dst := make([]int, len(src))
copy(dst, src)
// concise form
dst2 := append([]int(nil), src...)
src[0] = 99
fmt.Println(src, dst, dst2)
}