go / expert
Snippet
Zero-Copy String and Byte Conversions via modern unsafe Package API
Go 1.17 and 1.20 introduced unsafe.Slice, unsafe.SliceData, unsafe.String, and unsafe.StringData to replace reflection-based struct hacking on StringHeader and SliceHeader. This provides explicit, compiler-supported zero-copy casting between immutable strings and byte slices for hot-path I/O operations.
snippet.go
go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package mainimport ("fmt""unsafe")// BytesToString performs a zero-allocation conversion from []byte to string.// Safety: The underlying byte slice must not be mutated while the string is in use.func BytesToString(b []byte) string {if len(b) == 0 {return ""}return unsafe.String(unsafe.SliceData(b), len(b))}// StringToBytes performs a zero-allocation conversion from string to []byte.// Safety: The returned slice must NEVER be mutated, as strings in Go are immutable.func StringToBytes(s string) []byte {if len(s) == 0 {return nil}return unsafe.Slice(unsafe.StringData(s), len(s))}func main() {data := []byte("High-Performance Go")str := BytesToString(data)fmt.Printf("String: %s (len=%d)\n", str, len(str))strOrig := "Immutable Buffer"bytes := StringToBytes(strOrig)fmt.Printf("Bytes: %v (len=%d)\n", bytes, len(bytes))}
Breakdown
1
return unsafe.String(unsafe.SliceData(b), len(b))
Obtains a raw pointer to the first element of the byte slice using unsafe.SliceData and constructs a string view over the memory without allocating new heap memory.
2
return unsafe.Slice(unsafe.StringData(s), len(s))
Extracts the underlying read-only byte pointer of the string via unsafe.StringData and wraps it into a byte slice header without duplicating memory.