我有以下代码(Go Playground Example)定义了一个切片(内部将创建一个数组,并将切片的指针设置为内存中的数组位置),然后向其附加新值...
s := []int{1, 2, 3, 4}
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&s))
data := *(*[4]int)(unsafe.Pointer(hdr.Data))
fmt.Printf("slice: %T\n\t%#v\n\tlen: %d\n\tcap: %d\n", s, s, len(s), cap(s))
fmt.Printf("hdr: %#v\n", hdr) // &reflect.SliceHeader{Data:0x40e020, Len:4, Cap:4}
fmt.Printf("data: %#v\n", data) // [4]int{1, 2, 3, 4}
s = append(s, 5)
hdr = (*reflect.SliceHeader)(unsafe.Pointer(&s))
data = *(*[4]int)(unsafe.Pointer(hdr.Data))
fmt.Printf("slice: %T\n\t%#v\n\tlen: %d\n\tcap: %d\n", s, s, len(s), cap(s))
fmt.Printf("hdr: %#v\n", hdr) // &reflect.SliceHeader{Data:0x45e020, Len:5, Cap:8}
fmt.Printf("data: %#v\n", data) // [4]int{1, 2, 3, 4}
我在这段代码中遇到的问题是最后一行,该行指示尽管添加新值将导致重新创建基础数组(因为需要重新调整大小),但data
变量报告的值似乎显示原始数组内容(例如,长度为4)而不是更新的内容。
即使这是我们从中提取SliceHeader
字段的Data
所显示的基础数组的长度,其预期的[[updated长度为5?
[8]int{1, 2, 3, 4, 5, 0, 0, 0}
的内容。谢谢!
*[4]int
,即长度为4的数组的指针。除了4以外,它还能有什么长度?这样做是可以的,但是您将只能访问基础较大数组的前4个元素。而是使用[8]int
:
data2 := *(*[8]int)(unsafe.Pointer(hdr.Data))
fmt.Printf("data: %#v\n", data2) // [8]int{1, 2, 3, 4, 5, 0, 0, 0}
这将输出(在Go Playground上尝试):
data: [8]int{1, 2, 3, 4, 5, 0, 0, 0}