Go

When does converting between string and []byte NOT allocate?

Question 347MediumGo 1.22 to 1.25

In general, string(b) and []byte(s) copy the data, because strings are immutable and byte slices are not. The compiler removes the copy in patterns where it can prove the result is never kept or mutated:

func examples(m map[string]int, b []byte, s string) {
    _ = m[string(b)]            // map lookup key: no allocation
    if string(b) == "GET" {}    // comparison: no allocation
    _ = "prefix" + string(b)    // concatenation operand: no extra copy
    for i, c := range []byte(s) { _, _ = i, c } // range: no allocation
    switch string(b) {          // switch on converted value: no allocation
    case "a":
    }
}

Short conversions whose result does not escape may also use a 32-byte stack buffer and skip the heap. Map assignment m[string(b)] = 1 does allocate, because the key is stored.

If you truly need zero-copy conversion in other places, use unsafe.String / unsafe.Slice, but only when you can guarantee the bytes are never modified afterwards (covered below).

What the interviewer is looking for: you know these optimisations exist and can check them with -gcflags=-m or AllocsPerRun, instead of reaching for unsafe first.

More on Memory, GC & Runtime Internals

All 38 Memory, GC & Runtime Internals questions