GGistDev

Slices in Go

Slices are dynamic views over arrays with length and capacity. They are idiomatic for collections.

Create

Create nil, literal, or allocated slices. make lets you specify length and optional capacity.

var a []int                 // nil slice (len=0, cap=0)
b := []int{1,2,3}           // literal
c := make([]int, 3)         // len=3, zeroed
 d := make([]int, 0, 8)      // len=0, cap=8
_ = a; _ = b; _ = c; _ = d

Append

append adds elements, growing capacity when needed. When reallocated, a new backing array is created.

s := []int{}
s = append(s, 1)
s = append(s, 2, 3)
s = append(s, []int{4,5}...) // spread

Copy

copy(dst, src) copies up to min(len(dst), len(src)) elements from src into dst.

src := []int{1,2,3}
dst := make([]int, len(src))
copy(dst, src) // copies min(len(dst), len(src))

Slicing

Slicing is half-open: a[i:j] includes i up to j-1. Defaults: a[:j] is from 0, a[i:] to end, a[:] copies header.

xs := []int{0,1,2,3,4,5}
sub := xs[1:4]   // [1,2,3]
head := xs[:3]   // [0,1,2]
tail := xs[3:]   // [3,4,5]

Capacity growth

  • append may grow capacity (usually approx doubling)
  • Reallocation returns a new backing array; previous slices are unaffected
s := make([]int, 0, 1)
s = append(s, 1)
old := s
s = append(s, 2) // may reallocate
_ = old // old may still reference the old array

Zero value and nil

var z []int
fmt.Println(z == nil, len(z), cap(z)) // true, 0, 0
z = append(z, 1) // ok

Remove element (pattern)

// remove index i (preserve order)
s = append(s[:i], s[i+1:]...)

// remove without preserving order
s[i] = s[len(s)-1]
s = s[:len(s)-1]

Preallocate

n := 1000
xs = make([]int, 0, n)
for i := 0; i < n; i++ { xs = append(xs, i) }

Pitfalls

  • Slices share backing arrays; copying a slice copies the header, not data
  • Sub-slices keep the original array alive; use copy to detach if needed
  • Iterating and mutating: range over indices when changing elements
  • Taking addresses of range values points to the loop variable; index into the slice to take element addresses

Summary

  • Use slices for dynamic collections
  • Mind shared backing arrays and capacity growth
  • Preallocate when size is known for performance