Slices
Treat slices as views over arrays with length, capacity, and aliasing behavior that matter in APIs.
Canonical guidance
- remember slices share backing arrays until a copy or reallocation breaks sharing
- use
copywhen ownership should be distinct - reason about length and capacity when appending
Use when
- ordered collections
- buffers
- batched processing
Avoid
- returning subslices that accidentally retain large backing arrays
- mutating shared slices without clear ownership
- assuming append always mutates in place
Preferred pattern
func Clone(in []byte) []byte {
out := make([]byte, len(in))
copy(out, in)
return out
}
Anti-pattern
- keeping a tiny subslice of a huge buffer alive for a long time
Explanation: This anti-pattern is tempting because subslices are cheap, but they can retain far more memory than intended.
Why
- slice semantics are simple once ownership and aliasing stay explicit
Related pages
Sources
- The Go Programming Language Specification - Go Team
- Effective Go - Go Team