arrays - Go代码为更新的 slice 报告了错误的基础数组?

标签 arrays go slice

我有以下代码(Go Playground Example)定义了一个 slice (内部将创建一个数组,并将 slice 的指针设置为内存中的数组位置),然后向其附加新值...

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将基础数组的长度显示为预期的更新长度为5?

我在这里想念什么。为什么最后一行不能打印类似[8]int{1, 2, 3, 4, 5, 0, 0, 0}的内容。

谢谢!

最佳答案

这是因为在追加之后,您将使用更新后的slice头中的数据指针,但仍将数据指针转换为*[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}

关于arrays - Go代码为更新的 slice 报告了错误的基础数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58953213/

相关文章:

php - 如何使用 php 查找特定字符以从字符串创建数组

json - 查找 JSON 文件的嵌套结构的值

go - 如何使用 Go reflect 向 cron 添加功能?

string - 删除字符串中包含 slice 中单词的所有单词

arrays - 从值为空字符串的数组中删除字典(使用高阶函数)

c++ - 内存泄漏与否?

css - 各种 Adob​​e Fireworks CS4 查询

python - 在 Python 中切掉列表中每个(列表)元素中的第一个元素

javascript - 从仅包含发送的查询的数组中排除结果。 MongoDB

go - 处理 panic 和延迟函数