liveBook · Manning

Concatenation

As explained in 100 Go Mistakes and How to Avoid Them

String concatenation is the operation of joining multiple strings into one string value.

A common mistake is concatenating a slice of strings with += inside a loop and overlooking string immutability. Each iteration reallocates a new string and copies content, so the function can become significantly slower as the result grows. section 5.4

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

This implementation is simple and correct, but repeatedly reallocates the result during the loop. section 5.4

Use strings.Builder when joining many strings. Its WriteString method appends data to an internal buffer, minimizing memory copying; Write, WriteByte, and WriteRune support other input forms. The ignored error is intentional because WriteString does not return a non-nil error, while its signature satisfies io.StringWriter. section 5.4

func concat(values []string) string {
    sb := strings.Builder{}               #1
    for _, value := range values {
        _, _ = sb.WriteString(value)      #2
    }
    return sb.String()                    #3
}

This version builds the result with strings.Builder and returns the completed value with String. section 5.4

Choose the implementation according to the workload:

  • Call Grow when the total byte length is known. Preallocating the builder reduces additional growth and can improve performance. section 5.4
  • Do not use one strings.Builder concurrently: its internal byte slice is appended to during writes, so concurrent calls can race. section 5.4
  • Benchmarks show the += version at 72,291,485 ns/op, the basic Builder version at 878,962 ns/op, and the Grow version at 190,340 ns/op. section 5.4

How 100 Go Mistakes and How to Avoid Them covers it

How deep it goes
Explains immutability, repeated allocation, Builder buffering, preallocation, interface errors, and concurrency limits.
Examples
Uses loop-based concat functions, Builder variants, Grow preallocation, and comparative benchmark results.
What it assumes
Assumes basic Go strings and slices while teaching string immutability and Builder behavior.
What you can do after
Build it from scratch with strings.Builder, optionally calling Grow when the resulting byte length is known.
How it connects
Connects string immutability with strings.Builder, io.StringWriter, byte slices, runes, and slice preallocation.

Also explained in

Compare how 10 books explain concatenation →

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.