Monday, February 9, 2026
Array & Slice
Akash AmanUpdated: February 2026
Arrays
Fixed-Length Containers ([n]T)
Concept: An array is a numbered sequence of elements of a specific length. In Go, the size is part of the type. This means [3]int and [4]int are entirely different types and cannot be assigned to each other.
Setup:
- Behavior: Arrays are Value Types. When you assign an array to a new variable or pass it to a function, Go creates a complete copy of the data.
- Why: Use arrays when you need strict memory layout or when the data size is a known mathematical constant (e.g., a transformation matrix or cryptographic hash).
Multi-Dimensional Arrays
Concept: Arrays can be nested to create grids or matrices.
Behavior:
- Why: Useful for coordinate systems or representing structured data like a chessboard or a pixel grid where the dimensions never change.
Slices
The Slice Header ([]T)
Concept: A slice is a lightweight structure (a "descriptor") that points to an underlying array. It consists of three fields: a Pointer to the data, a Length, and a Capacity.
Setup:
- Behavior: Slices are Reference-like. Passing a slice to a function only copies the 24-byte header (on 64-bit systems), not the underlying data. Modifying elements inside a function affects the original caller.
- Why: Slices are the "workhorse" of Go because they allow for flexible, dynamic collections without the overhead of copying large amounts of data.
Length vs. Capacity
Concept: - Length (len): The number of elements currently in the slice.
- Capacity (
cap): The number of elements in the underlying array, starting from the first element in the slice.
Behavior:
- When you
appendto a slice and exceed its capacity, Go allocates a new, larger array, copies the data, and returns a new header pointing to the new memory.
- Why: Understanding capacity helps you optimize performance. If you know you'll need 1,000 items, using
make([]T, 0, 1000)prevents dozens of unnecessary memory allocations.
Essential Slice Operations
The Append Function
Concept: The built-in append adds elements to the end of a slice.
Behavior:
- Why: It handles the complex logic of checking capacity and re-allocating memory automatically, providing a simple API for dynamic growth.
The Copy Function
Concept: copy(dest, src) clones elements from one slice to another.
Behavior:
- It only copies up to the minimum of
len(dest)orlen(src). - It handles overlapping slices correctly (moving data within the same array).
- Why: Essential when you want to create a "snapshot" of data that won't change if the original underlying array is modified.
Slicing Mechanics
Sub-slicing (Windows)
Concept: You can create a new slice from an existing one using slice[low:high].
Behavior:
- Crucial Note:
q1andmonthsshare the same memory. Changingq1[0]to "Zero" will makemonths[0]also "Zero". - Why: This is extremely efficient for processing subsets of data (like reading a specific header from a network packet) without copying bytes.
Reference Guides
Summary Table: Array vs. Slice
| Feature | Array ([n]T) | Slice ([]T) |
|---|---|---|
| Size | Fixed (part of the type) | Dynamic (growable) |
| Passing | Passed by Value (Copies all) | Passed by Reference (Copies header) |
| Storage | Contiguous memory | Header pointing to contiguous memory |
| Common Use | Low-level optimization | 99% of general Go development |
Common Gotchas for Newbies
| Scenario | What happens? |
|---|---|
| Passing Array to Function | The function gets a copy; changes don't persist outside. |
| Append without Assignment | append(s, val) does nothing. You must use s = append(s, val). |
| Zero-Value | var a [2]int is [0, 0]. var s []int is nil. |
| Out of Bounds | Accessing an index >= len causes a panic, even if it is < cap. |