In Go, slices are references to underlying arrays and their headers store information about the length and capacity of the slice, as well as a pointer to the underlying data. While the contents of a slice can be modified, its header typically remains the same.
Consider the following code snippet:
var buffer [256] byte func SubtractOneFromLength(slice []byte) []byte { slice = slice[0 : len(slice)-1] return slice } func main() { slice := buffer[10:20] fmt.Println("Before: len(slice) =", len(slice)) newSlice := SubtractOneFromLength(slice) fmt.Println("After: len(slice) =", len(slice)) fmt.Println("After: len(newSlice) =", len(newSlice)) newSlice2 := SubtractOneFromLength(newSlice) fmt.Println("After: len(newSlice2) =", len(newSlice2)) }
When the function SubtractOneFromLength is called, it modifies the slice but not the slice header. To inspect the slice header, you can use the reflect.SliceHeader type.
type SliceHeader struct { Data uintptr Len int Cap int }
The following unsafe operation demonstrates how to convert a slice pointer to a *reflect.SliceHeader:
sh := (*reflect.SliceHeader)(unsafe.Pointer(&newSlice2))
You can then print the contents of the header using the format string % v:
fmt.Printf("%+v", sh)
The Go Playground produces the following output:
&{Data:1792106 Len:8 Cap:246}
This output provides the memory address of the underlying data (Data), the length of the slice (Len), and its capacity (Cap).
Without unsafe:
Accessing the slice header information without unsafe is also possible:
The above is the detailed content of How Can I Inspect the Header of a Go Slice Safely and Unsafely?. For more information, please follow other related articles on the PHP Chinese website!