V
Vel·ToolKit
Simple · Fast · Ready to use
EN
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)
}