liveBook · Manning

Immutable collection

As explained in 100 Go Mistakes and How to Avoid Them

Immutability is the property that a value or data object cannot be changed after creation.

A common mistake is treating a Go string like a mutable buffer. A string cannot be changed after creation, so repeated += concatenation reallocates a new string and copies data on every iteration. section 5.4

func concat(values []string) string {
    s := ""
    for _, value := range values {
        s += value
    }
    return s
}

This implementation appears simple but repeatedly constructs new strings. section 5.4

Choose the representation according to the operation:

  • Use strings.Builder when constructing a result string incrementally; WriteString appends to an internal buffer and reduces copying. section 5.4
  • Call Grow when the final size is known, allowing the builder to preallocate its internal byte slice. section 5.4
  • Use []byte throughout a byte-oriented workflow when possible, avoiding []byte-to-string and string-to-[]byte conversions. section 5.5
func concat(values []string) string {
    sb := strings.Builder{}               #1
    for _, value := range values {
        _, _ = sb.WriteString(value)      #2
    }
    return sb.String()                    #3
}

The builder version preserves the string result while accumulating content in a mutable internal buffer. section 5.4

A conversion does not preserve a mutable view

Converting a byte slice to a string copies its bytes. Changing the original slice afterward therefore leaves the string unchanged: a, b, c becomes a, x, c only in the slice, not in the string. section 5.5

b := []byte{'a', 'b', 'c'}
s := string(b)
b[1] = 'x'
fmt.Println(s)

This small experiment makes string immutability observable by modifying the original byte slice after conversion. section 5.5

How 100 Go Mistakes and How to Avoid Them covers it

How deep it goes
Explains immutability through allocation behavior, byte copying, builder buffering, preallocation, and conversion examples.
Examples
Uses repeated concatenation, strings.Builder, Builder.Grow, byte-slice sanitization, and a byte-to-string mutation experiment.
What it assumes
Assumes familiarity with Go strings, slices, loops, and package functions while demonstrating immutability through concrete code.
What you can do after
Diagnose unnecessary allocations and choose strings.Builder or byte-slice processing for appropriate workflows.
How it connects
Connects immutable strings with strings.Builder, byte slices, strings, bytes, interfaces, and memory allocation.

Also explained in

Compare how 24 books explain immutable collection →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 Go Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.