strings.Builder records the intent to assemble text from smaller pieces.

builder For repeated string assembly, a builder makes the work explicit and keeps appends in one place.

String Builder Work

repeat
string_builder_work.go
Replay: real traced execution (multi-file project)
package main

import (
	"fmt"
	"strings"
)

func main() {
	var repeat = 3
	var builder strings.Builder
	for i := 0; i < repeat; i++ {
		builder.WriteString("go")
	}
	result := builder.String()

	fmt.Println("repeat=", repeat)
	fmt.Println("length=", len(result))
	fmt.Println("result=", result)
	fmt.Println("empty=", result == "")
}
package main

import (
	"fmt"
	"strings"
)

func main() {
	var repeat = 1
	var builder strings.Builder
	for i := 0; i < repeat; i++ {
		builder.WriteString("go")
	}
	result := builder.String()

	fmt.Println("repeat=", repeat)
	fmt.Println("length=", len(result))
	fmt.Println("result=", result)
	fmt.Println("empty=", result == "")
}
package main

import (
	"fmt"
	"strings"
)

func main() {
	var repeat = 5
	var builder strings.Builder
	for i := 0; i < repeat; i++ {
		builder.WriteString("go")
	}
	result := builder.String()

	fmt.Println("repeat=", repeat)
	fmt.Println("length=", len(result))
	fmt.Println("result=", result)
	fmt.Println("empty=", result == "")
}
  1. repeat ← 3, builder ← strings.Builder{addr:(*strings.Builder)(nil), buf:[]uint8(nil)}

    8func main() {9  var repeat→ 3 = 3 //@repeat=1, 510  var builder→ strings.Builder{addr:(*strings.Builder)(nil), buf:[]uint8(nil)} strings.Builder11  for i := 0; i < repeat; i++ {
  2. builder ← strings.Builder{addr:(*strings.Builder)(⟨addr A⟩), buf:[]uint8{0x67, 0x6f}}

    pass 1 of 3
    10var builder strings.Builder11for i0 := 0; i < repeat3; i++ {12  builder→ strings.Builder{addr:(*strings.Builder)(⟨addr A⟩), buf:[]uint8{0x67, 0x6f}}.WriteString("go")13}
    All 3 passes — pass 1 is the card above
    passibuilder
    10strings.Builder{addr:(*strings.Builder)(nil), buf:[]uint8(nil)} strings.Builder{addr:(*strings.Builder)(⟨addr A⟩), buf:[]uint8{0x67, 0x6f}}
    21strings.Builder{addr:(*strings.Builder)(⟨addr A⟩), buf:[]uint8{0x67, 0x6f}} strings.Builder{addr:(*strings.Builder)(⟨addr A⟩), buf:[]uint8{0x67, 0x6f, 0x67, 0x6f}}
    32strings.Builder{addr:(*strings.Builder)(⟨addr A⟩), buf:[]uint8{0x67, 0x6f, 0x67, 0x6f}} strings.Builder{addr:(*strings.Builder)(⟨addr A⟩), buf:[]uint8{0x67, 0x6f, 0x67, 0x6f, 0x67, 0x6f}}
  3. result ← "gogogo"

    13  }14  result→ "gogogo" := builderstrings.Builder{addr:(*strings.Builder)(⟨addr A⟩), buf:[]uint8{0x67, 0x6f, 0x67, 0x6f, 0x67, 0x6f}}.String()1516  fmt.Println("repeat=", repeat3)17  fmt.Println("length=", len(result"gogogo"))18  fmt.Println("result=", result"gogogo")19  fmt.Println("empty=", result"gogogo" == "")20}
    outputrepeat= 3
    length= 6
    result= gogogo
    empty= false
  1. repeat ← 1, builder ← strings.Builder{addr:(*strings.Builder)(nil), buf:[]uint8(nil)}

    8func main() {9  var repeat→ 1 = 110  var builder→ strings.Builder{addr:(*strings.Builder)(nil), buf:[]uint8(nil)} strings.Builder11  for i := 0; i < repeat; i++ {
  2. builder ← strings.Builder{addr:(*strings.Builder)(⟨addr A⟩), buf:[]uint8{0x67, 0x6f}}

    10var builder strings.Builder11for i0 := 0; i < repeat1; i++ {12  builder→ strings.Builder{addr:(*strings.Builder)(⟨addr A⟩), buf:[]uint8{0x67, 0x6f}}.WriteString("go")13}
  3. result ← "go"

    13  }14  result→ "go" := builderstrings.Builder{addr:(*strings.Builder)(⟨addr A⟩), buf:[]uint8{0x67, 0x6f}}.String()1516  fmt.Println("repeat=", repeat1)17  fmt.Println("length=", len(result"go"))18  fmt.Println("result=", result"go")19  fmt.Println("empty=", result"go" == "")20}
    outputrepeat= 1
    length= 2
    result= go
    empty= false
  1. repeat ← 5, builder ← strings.Builder{addr:(*strings.Builder)(nil), buf:[]uint8(nil)}

    8func main() {9  var repeat→ 5 = 510  var builder→ strings.Builder{addr:(*strings.Builder)(nil), buf:[]uint8(nil)} strings.Builder11  for i := 0; i < repeat; i++ {
  2. builder ← strings.Builder{addr:(*strings.Builder)(⟨addr A⟩), buf:[]uint8{0x67, 0x6f}}

    pass 1 of 5
    10var builder strings.Builder11for i0 := 0; i < repeat5; i++ {12  builder→ strings.Builder{addr:(*strings.Builder)(⟨addr A⟩), buf:[]uint8{0x67, 0x6f}}.WriteString("go")13}
    All 5 passes — pass 1 is the card above
    passibuilder
    10strings.Builder{addr:(*strings.Builder)(nil), buf:[]uint8(nil)} strings.Builder{addr:(*strings.Builder)(⟨addr A⟩), buf:[]uint8{0x67, 0x6f}}
    21strings.Builder{addr:(*strings.Builder)(⟨addr A⟩), buf:[]uint8{0x67, 0x6f}} strings.Builder{addr:(*strings.Builder)(⟨addr A⟩), buf:[]uint8{0x67, 0x6f, 0x67, 0x6f}}
    32strings.Builder{addr:(*strings.Builder)(⟨addr A⟩), buf:[]uint8{0x67, 0x6f, 0x67, 0x6f}} strings.Builder{addr:(*strings.Builder)(⟨addr A⟩), buf:[]uint8{0x67, 0x6f, 0x67, 0x6f, 0x67, 0x6f}}
    43strings.Builder{addr:(*strings.Builder)(⟨addr A⟩), buf:[]uint8{0x67, 0x6f, 0x67, 0x6f, 0x67, 0x6f}} strings.Builder{addr:(*strings.Builder)(⟨addr A⟩), buf:[]uint8{0x67, 0x6f, 0x67, 0x6f, 0x67, 0x6f, 0x67, 0x6f}}
    54strings.Builder{addr:(*strings.Builder)(⟨addr A⟩), buf:[]uint8{0x67, 0x6f, 0x67, 0x6f, 0x67, 0x6f, 0x67, 0x6f}} strings.Builder{addr:(*strings.Builder)(⟨addr A⟩), buf:[]uint8{0x67, 0x6f, 0x67, 0x6f, 0x67, 0x6f, 0x67, 0x6f, 0x67, 0x6f}}
  3. result ← "gogogogogo"

    13  }14  result→ "gogogogogo" := builderstrings.Builder{addr:(*strings.Builder)(⟨addr A⟩), buf:[]uint8{0x67, 0x6f, 0x67, 0x6f, 0x67, 0x6f, 0x67, 0x6f, 0x67, 0x6f}}.String()1516  fmt.Println("repeat=", repeat5)17  fmt.Println("length=", len(result"gogogogogo"))18  fmt.Println("result=", result"gogogogogo")19  fmt.Println("empty=", result"gogogogogo" == "")20}
    outputrepeat= 5
    length= 10
    result= gogogogogo
    empty= false