Zero-copy string to []byte conversion via unsafe in Go
Go memory layout and unsafe trade-offs.
use unsafe.StringData/Slice (or reflect headers) to alias the string's bytes without copying; assumes shared backing array; risk is mutating an immutable string.
WHAT THIS TESTS Whether you understand Go's internal representation of strings and slices, why the standard conversion copies, and how to alias safely with unsafe while respecting immutability.
A GOOD ANSWER COVERS A conversion like []byte(s) or string(b) allocates and copies because strings are immutable and slices are mutable, so Go cannot share the backing array safely in general. In a genuinely hot path, for example zero-allocation parsing of large request bodies or building map keys from byte buffers, you can skip the copy by aliasing the same memory. On modern Go the idiomatic form uses the unsafe helpers: for string to bytes, unsafe.Slice(unsafe.StringData(s), len(s)); for bytes to string, unsafe.String(unsafe.SliceData(b), len(b)). These construct a header pointing at the existing backing array with no allocation. The layout assumption is that a string is a pointer plus length and a slice is a pointer, length, and capacity sharing that pointer.
COMMON WRONG ANSWERS Writing through the []byte obtained from a string; strings are immutable and the bytes may live in read-only memory, so this is undefined behavior that can corrupt interned strings or crash. Forgetting the source must stay reachable so the GC does not free the backing array. Hand-rolling reflect.StringHeader and SliceHeader, which are now discouraged and easy to misuse.
LIKELY FOLLOW-UPS Why is the bytes-to-string direction safer than string-to-bytes? How does this interact with the garbage collector and pointer liveness? When does the compiler already elide the copy, such as a string conversion used only as a map key? What guarantees does the unsafe.Pointer rule set require?
ONE CONCRETE EXAMPLE In a parser hashing many substrings, b := unsafe.Slice(unsafe.StringData(s), len(s)) lets you feed s into a byte-oriented hash without allocating a copy per token. You treat b as strictly read-only and ensure s outlives b. Mutating b would violate string immutability and risk corrupting other holders of the same string, which is the central risk.
Read the original → pkg.go.dev
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.