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























