unsafe and slice
- Go course
- Advanced
- Lesson 11/68
- 4 min
Learn the array behind a slice with unsafe.
Slices and strings with unsafe
unsafe.String, unsafe.StringData, unsafe.Slice and unsafe.SliceData, added in Go 1.20, replaced old reflect.SliceHeader tricks. You can view a []byte as a string without copying:
b := []byte("merhaba")
s := unsafe.String(&b[0], len(b))
fmt.Println(s) // merhabaThe other way: string → []byte
unsafe.Slice(unsafe.StringData(s), len(s)) gives a string's bytes as a slice without copying. Writing to this slice is forbidden; string constants may live in read-only memory and a write crashes the program. In most cases a plain []byte(s) copy is fast enough.
Practice Zero-copy conversion
Declare b := []byte("gopher"). Create a string with unsafe.String(&b[0], len(b)) and print the string and its length.
Starter code
package main
import (
"fmt"
"unsafe"
)
func main() {
// buraya yaz
}Sample solution
package main
import (
"fmt"
"unsafe"
)
func main() {
b := []byte("gopher")
s := unsafe.String(&b[0], len(b))
fmt.Println(s, len(s))
}Expected output
gopher 6
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 What is required for a string created without copying?
- The slice must be empty
- The string must be lower case
- GC must be disabled
- The underlying byte slice must not be modified later Correct answer
Explanation: Go strings are assumed immutable; if the bytes change, the same string shows different content and the program's behavior is undefined.
2 String without copying
b := []byte("go")
s := unsafe.____(&b[0], len(b))
b := []byte("go")
s := unsafe.String(&b[0], len(b))
Explanation: unsafe.String builds a string from a byte pointer and a length.
3 Go 1.20 unsafe functions
| Term | Meaning |
|---|---|
unsafe.String |
String from bytes |
unsafe.StringData |
Pointer to a string's bytes |
unsafe.Slice |
Slice from a pointer |
unsafe.SliceData |
Pointer to a slice's first element |