Skip to Content
Go Realm v1 is released 🎉
TopicsSlice

Slices in Go: Essential Guide

Basics of Slices

// Declaration & Initialization var empty []int // nil slice letters := []string{"a", "b"} // slice literal nums := make([]int, 3, 5) // length=3, capacity=5

Key Characteristics⭐

  • Dynamic size (unlike arrays)
  • Reference type (backed by an array)
  • Three components:
    • Pointer to underlying array
    • Length (number of elements)
    • Capacity (max size before reallocation)

Core Operations

Creating Slices

OperationExampleDescription
From arrayarr[1:4]Creates slice from array
From sliceslice[:3]New slice from existing
Makemake([]T, len, cap)Pre-allocated slice

Common Methods

s := []int{1, 2} s = append(s, 3) // [1, 2, 3] copy(dest, src) // Copies elements len(s), cap(s) // Get dimensions

Critical Points to Remember

  1. Underlying Array Sharing⭐

    a := []int{1, 2, 3} b := a[:2] // Shares same array b[0] = 9 // Modifies a[0] too!
  2. Append Behavior

    • May allocate new array if capacity exceeded
    • Original slice unaffected if new allocation occurs
  3. Nil vs Empty

    var nilSlice []int // nil (len=0, cap=0) empty := []int{} // non-nil (len=0, cap=0)
  4. Capacity Rules.⭐

    • Append doubles capacity until 1024 elements
    • Then grows by 25% each time

Performance Considerations

Do:

  • Pre-allocate with make() when size is known
  • Reuse slices with slice = slice[:0] (clear without reallocation)

Don’t:

  • Append in loops without pre-allocation
  • Assume append won’t modify original slice
  • Forget that subslices share memory

Common Pitfalls

  1. Memory Leaks

    func leak() []int { big := make([]int, 1e6) return big[:10] // Holds reference to 1M elements! }
  2. Accidental Modifications

    original := []int{1, 2, 3} subset := original[1:3] subset[0] = 9 // Modifies original[1]
  3. Append Gotchas

    s := []int{1, 2, 3} s = append(s, 4) // May or may not modify original

📚 FAQ

❓ What is a slice in Go?

A slice is a dynamically-sized, flexible view into the elements of an array. Unlike arrays, slices can grow and shrink.


❓ How is a slice different from an array in Go?

  • Arrays have a fixed size; slices are dynamically sized.
  • Arrays are value types; slices are reference types.
  • Slices internally contain a pointer to the array, length, and capacity.

❓ What is the zero value of a slice?

The zero value of a slice is nil, which has a length and capacity of 0.


❓ How do you create a slice in Go?

s := []int{1, 2, 3} // Using a literal s := make([]int, 5) // Using make s := arr[1:4] // Slicing an array or slice

❓ What are length and capacity of a slice?

  • len(slice) → number of elements.
  • cap(slice) → number of elements in the underlying array from the start index to the end.

❓ Can slices be resized in Go?

Yes. You can append to a slice using append(), which may create a new underlying array.


❓ What happens when a slice exceeds its capacity?

Go allocates a new array (usually double the size), copies the existing elements to it, and returns a new slice.


❓ Are slices passed by reference or value?

Slices are passed by value, but since they contain a reference to the underlying array, changes to elements inside the function affect the original data.


❓ How do you copy a slice?

Use the built-in copy() function:

dst := make([]int, len(src)) copy(dst, src)

❓ How do you delete an element from a slice?

Use slicing and append():

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

❓ Can you compare two slices using ==?

No. Only nil slices can be compared using ==. For deep equality, use reflect.DeepEqual() or manually compare elements.


❓ What is the difference between nil slice and empty slice?

  • var s []intnil slice (len=0, cap=0, s==nil)
  • s := []int{} → empty slice (len=0, cap=0, s!=nil)

❓ What is the underlying structure of a slice? 🔥🔥

A slice internally contains:

type slice struct { ptr *T // pointer to array len int // current number of elements cap int // max elements before resizing }

❓ What happens when you append to a nil slice?

Appending to a nil slice works the same as appending to an empty slice. Go allocates the memory as needed.


❓ Can you slice a slice?

Yes. You can slice a slice multiple times:

s1 := []int{1, 2, 3, 4} s2 := s1[1:3] // s2 = [2, 3]

⚡ Array vs Slice in Go

FeatureArraySlice
SizeFixedDynamic (can grow/shrink)
TypeValue typeReference type
MemoryAll data copied on assignmentOnly slice descriptor copied (shallow copy)
Creationvar a [5]intvar s []int or slicing an array
Common UseRare (low-level memory control)Very common
PerformanceNo hidden costSome overhead due to dynamic growth and possible copying