gpt4 book ai didi

arrays - golang 中的 0 长度 slice 和数组

转载 作者:IT王子 更新时间:2023-10-29 02:34:10 26 4
gpt4 key购买 nike

试图弄清楚长度为 0 的数组和 slice 在 Golang 中的行为方式。提出了两个代码片段(我在某处找到了代码并对其进行了一些修改以使用它)

https://play.golang.org/p/ew2YYgvpGC

https://play.golang.org/p/jm2p6L6WCG

从网站上得知nil数组([]int(nil))的指针值为nil,于是决定测试一下。果然如此。我只是对制作和 slice 数组感到困惑。它有我意想不到的行为。

这两个人的行为我真的很困惑。第一个在我的电脑和 Playground 上运行良好。我注意到第一个和最后一个数组的地址总是完全相同?为什么?

这是为什么?

第二个更奇怪。这与前一个代码完全相同,只是中间有 len/cap 的其他代码片段。它不会在 go playground 上运行, slice 数组的最后一个错误,由于某种原因, slice 的长度为 3(在我的计算机上,最后一个为 0,所有的上限其中有 272851504)。但是它确实在我的电脑上运行。我注意到用 make 创建的第一个数组的地址总是比最后一个小。它总是不同的,而且有点小(第一个),为什么?数组地址的代码没有变化

另外,为什么 make() 甚至创建一个数组?长度为 0 的数组在内存中看起来如何?

最佳答案

I've noticed that the address of the first and last array is always the exact same? Why?

Why is this?

您将函数中的地址基于函数参数中的 slice header 。碰巧这个函数每次都在相同的内存地址运行。此外,作为一个实现细节,当您将原始数据 slice 为零长度和容量时,它不会将数据指针清零。在您的两个函数中,都复制了 slice header ,因此您甚至没有检查原始 header slice 。

第二个示例,您没有正确读取 slice header 。如果你想玩,不用尝试做指针运算,直接取slice的地址就可以了

hdr := (*reflect.SliceHeader)(unsafe.Pointer(&slice))

不过,如果你真的想通过指针算法检查 slice 头,也许这可以更好地阐明你需要做什么:https://play.golang.org/p/GL6NtyPNs8

func InspectSlice(slice *[]int) {
// Get the header directly by converting it to a reflect.SliceHeader
hdr := (*reflect.SliceHeader)(unsafe.Pointer(slice))

// Create a header for comparison via pointer manipulation
address := (uintptr)(unsafe.Pointer(slice))
lenAddr := address + unsafe.Sizeof(address)
capAddr := lenAddr + unsafe.Sizeof(int(0))

unsafeHdr := reflect.SliceHeader{
Data: *(*uintptr)(unsafe.Pointer(address)),
Len: *(*int)(unsafe.Pointer(lenAddr)),
Cap: *(*int)(unsafe.Pointer(capAddr)),
}

fmt.Printf("Real Header: %#v\n", *hdr)
fmt.Printf("UnsafeHeader: %#v\n", unsafeHdr)

}

Also, why does make() even create an array?

Make 不会创建数组,您标记为 array 的只是一个 slice 文字。

How does an array of length 0 even look in memory?

看起来没什么。它消耗 0 个字节。

制作零长度 slice 时,您看到的很可能是指向全局零值数组的指针。制作一堆不同类型的零长度 slice ,数据指针将全部相同。正如所有空的 struct{} 和空的 nil interface{} 都被赋予相同的值作为优化。这完全是一个实现细节,因为您不应该访问该数据值。将 slice slice 回零长度和容量时,运行时也不会将数据指针清零。由于这两种行为,任何 slice 中的数据指针很少会为 nil。

关于arrays - golang 中的 0 长度 slice 和数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29216252/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com