Unsafe Code
Overview
The unsafe package bypasses Go’s type safety. Use only when absolutely necessary for performance or interoperability.
unsafe.Pointer
import "unsafe"
// Convert between pointer types
var x int = 42
p := unsafe.Pointer(&x)
fp := (*float64)(p) // Reinterpret as float64 pointerCommon Uses
Memory Layout
type Data struct {
a int32
b int64
}
fmt.Println(unsafe.Sizeof(Data{})) // Size in bytes
fmt.Println(unsafe.Alignof(Data{})) // Alignment
fmt.Println(unsafe.Offsetof(Data{}.b)) // Field offsetString to Bytes (Zero-Copy)
func stringToBytes(s string) []byte {
return unsafe.Slice(unsafe.StringData(s), len(s))
}Accessing Unexported Fields
// Not recommended, but possible
type hidden struct {
secret int
}
h := hidden{secret: 42}
p := unsafe.Pointer(&h)
secretPtr := (*int)(p)
fmt.Println(*secretPtr)Dangers
- Not portable across platforms
- May break with Go versions
- Undefined behavior if misused
- Bypasses garbage collector
Guidelines
- Avoid if possible - Use safer alternatives first
- Document thoroughly - Explain why unsafe is needed
- Isolate usage - Keep in small, well-tested functions
- Test extensively - Including on target platforms
Summary
| Function | Purpose |
|---|---|
unsafe.Pointer |
Generic pointer type |
unsafe.Sizeof |
Size in bytes |
unsafe.Alignof |
Alignment requirement |
unsafe.Offsetof |
Field offset |