2 回答
TA贡献1875条经验 获得超5个赞
首先,如果你还没有,你应该阅读这篇关于 slice internals 的官方博客文章。那应该清除一切。
现在访问的底层数组,你可以使用的组合reflect和unsafe。特别是,reflect.SliceHeader 包含一个Data字段,该字段包含一个指向切片底层数组的指针。
改编自unsafe包文档的示例:
s := []int{1, 2, 3, 4}
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&s))
data := *(*[4]int)(unsafe.Pointer(hdr.Data))
TA贡献2037条经验 获得超6个赞
就像一个提示,回答你的第二个问题。从Go 1.17开始,你可以这样做
(*[2]int)(numSlice)
package main
import (
"fmt"
)
func main() {
nums := [3]int{1, 2, 3}
numSlice := nums[:2]
underArr1 := (*[2]int)(numSlice)
fmt.Println(&underArr1[0]) //0xc000016018
numSlice = append(numSlice, 10)
underArr2 := (*[3]int)(numSlice)
fmt.Println(&underArr2[0]) //0xc000016018 - same
fmt.Println(nums) // [1 2 10]
numSlice = append(numSlice, 20)
underArr3 := (*[3]int)(numSlice)
fmt.Println(&underArr3[0]) //0xc000078030 - different
fmt.Println(cap(numSlice)) // 6
}
老实说,你不必转换为数组指针来查看地址,我只是为了回答你的第二个问题。
该行为确实是您描述的方式。当您追加 时10,您的底层数组中仍然剩下一个字段(因为它的长度是 3,但是您的 numSlice 是 2),即使它当前被 a 占用3,它也可以使用,并被3覆盖10。
当您附加 a 时20,没有剩余的字段,因此它会创建一个新的底层数组(很可能有 6 个字段长,两倍大)并将原始数组中的所有数据复制到那里,并将指针移动到该数组。
- 2 回答
- 0 关注
- 424 浏览
添加回答
举报