Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The [:] operator in Go is a slice expression that creates a new slice or string descriptor referencing the entirety of an existing array, pointer to an array, slice, or string. It acts as syntactic sugar for [0:len(operand)], generating a new view into the original contiguous memory block without copying the underlying data.

Syntax and Defaults

The general form of a simple slice expression is a[low:high]. When the indices are omitted, Go applies default bounds:
  • An omitted low index defaults to 0.
  • An omitted high index defaults to len(a).
Therefore, a[:] is strictly equivalent to a[0:len(a)].
a := [3]int{1, 2, 3}

// Using the [:] operator
fullSlice1 := a[:] 

// Equivalent explicit expression
fullSlice2 := a[0:len(a)]

Memory Mechanics and Escape Analysis

Applying the [:] operator does not allocate new memory for the underlying elements. Instead, it constructs a new internal runtime descriptor (such as runtime.slice or runtime.stringStruct). The allocation location of this new descriptor is determined by Go’s escape analysis. While it is often allocated on the stack, if the resulting descriptor escapes its scope (e.g., by being returned as a pointer or stored in an interface), it will be allocated on the heap. When applied to a slice or array, the resulting slice descriptor is populated as follows:
  • Data Pointer: Points to the memory address of the 0th element of the original operand.
  • Length (len): Set to the number of elements in the operand (len(a) - 0).
  • Capacity (cap): Set to the maximum capacity of the operand starting from the 0th index (cap(a) - 0).
Because the new slice shares the backing array with the original operand, any mutations to the elements through the new slice will be reflected in the original structure, provided the operand’s underlying memory is mutable.

Operand Behaviors and Addressability

The type resolution and specific behavior of [:] depend strictly on the type of the operand a:
  • Arrays ([N]T) and Pointers to Arrays (*[N]T): The operator evaluates the fixed-size array and returns a dynamically-sized slice ([]T). The resulting slice’s length and capacity are both equal to N.
    • Addressability Rule: To be sliced, an array must be addressable. Attempting to apply the [:] operator to an unaddressable array—such as an inline array literal or an array returned directly by value from a function—will result in a compiler error (invalid operation: ... (slice of unaddressable value)).
  • Slices ([]T): The operator creates a shallow copy of the slice descriptor. The new slice has the exact same length, capacity, and data pointer as the original slice.
  • Strings (string): Because strings are immutable in Go, applying [:] yields a new string (not a []byte) that shares the same underlying immutable byte array.
// Valid: Slicing an addressable array variable
var arr [5]int
slc1 := arr[:]     // Type: []int, Len: 5, Cap: 5 (Points to 'arr' memory)

// Invalid: Slicing an unaddressable array literal
// _ = [3]int{1, 2, 3}[:] 
// Compiler error: invalid operation: [3]int{...}[:] (slice of unaddressable value)

// Valid: Slicing an existing slice
slc2 := slc1[:]    // Type: []int, Len: 5, Cap: 5 (New descriptor, same backing array)

// Valid: Slicing a string
str := "golang"
str2 := str[:]     // Type: string, Len: 6 (New string descriptor, same backing bytes)
Master Go with Deep Grasping Methodology!Learn More