How do you convert between []byte and string without copying, and what are the risks?
Question 70HardGo 1.22 to 1.25
Go 1.20 added the supported primitives unsafe.String, unsafe.StringData and unsafe.SliceData. They replace the old reflect.StringHeader/SliceHeader hacks, which are now deprecated and broke under GC changes.
import "unsafe"
// []byte -> string, zero copy
func bytesToString(b []byte) string {
if len(b) == 0 {
return ""
}
return unsafe.String(unsafe.SliceData(b), len(b))
}
// string -> []byte, zero copy (result MUST be treated as read-only)
func stringToBytes(s string) []byte {
if s == "" {
return nil
}
return unsafe.Slice(unsafe.StringData(s), len(s))
}
Risks:
- Changing the bytes after converting to a string breaks immutability. Map keys holding that string get corrupted, and strings that callers cached change without warning.
- Writing to bytes taken from a string can segfault, because string literals live in read-only memory. The runtime reports "unexpected fault address".
- If the source is reused or pooled (
sync.Pool), the string's contents change when the buffer is recycled.
When it is justified: hot paths found by profiling, such as parsers, serializers, or high-QPS proxies, where the source buffer is never changed afterwards. strings.Builder.String() uses this exact technique internally.
What the interviewer wants: you name the invariant ("the bytes must never be modified while the string is reachable"), you know the compiler already optimizes many conversions, and you measure before using unsafe.
More on Arrays, Slices, Maps & Strings
- Q68What does this print? (len, indexing and ranging over a UTF-8 string)
- Q69How do you build strings efficiently? Compare +, fmt.Sprintf, bytes.Buffer and strings.Builder.
- Q71How do you implement a set in Go, and what maps package helpers exist?
- Q72What does this print before and after Go 1.22? (taking &v and capturing i in loops)
- Q73What does this print? (map of slices built from a shared base)
- Q74What does this print? (range over a nil pointer to an array, and range over an int)