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
- Q345How does
sync.Poolbehave, and what are its pitfalls? - Q346How do you measure and assert allocation counts?
- Q348What does this print on a 64-bit platform, and why?
- Q349Explain 64-bit atomic alignment and false sharing. How do you lay out hot concurrent counters?
- Q350What are zero-sized types' memory semantics? What do these print?
- Q351What are the rules for valid
unsafe.Pointerusage?