为什么一个空切片有 24 个字节?
Why does an empty slice have 24 bytes?
我想了解使用 make([]int, 0)
创建空切片时会发生什么。我执行此代码进行测试:
emptySlice := make([]int, 0)
fmt.Println(len(emptySlice))
fmt.Println(cap(emptySlice))
fmt.Println(unsafe.Sizeof(emptySlice))
大小和容量return很明显,都是0,但是slice的大小是24字节,为什么?
24 字节应该是 3 int64
对吧?一个 24 字节的切片的内部数组应该是这样的:[3]int{}
,那么为什么一个空切片有 24 个字节?
Go 中的所有数据类型都是静态大小的。由于切片的动态特性,元素的数量与类型没有任何关联。
如果您阅读 unsafe.Sizeof
的 documentation,它会解释这里发生的事情:
The size does not include any memory possibly referenced by x. For instance, if x is a slice, Sizeof returns the size of the slice descriptor, not the size of the memory referenced by the slice.
unsafe.Sizeof
是对象在内存中的大小,和C、C++中的sizeof
完全一样。参见 How to get memory size of variable?
切片有大小,但也有调整大小的能力,所以最大调整大小的能力也必须存储在某处。但是可调整大小也意味着它不能是静态数组,而是需要存储指向其他(可能是动态分配的)数组的指针
整个事情意味着它需要存储它的 { begin, end, last valid index } or {开始,大小,容量}。这是一个包含 3 个值的元组,这意味着它在 64 位平台上的内存表示至少为 3×8 字节,除非您想将最大大小和容量限制为远小于 264字节
在许多具有相同动态大小调整功能的 C++ 类型中情况完全相同,例如 std::string
或 std::vector
也是 24 字节类型,尽管在某些实现中添加了 8 字节的填充对齐的原因,导致了一个 32 字节的字符串类型。参见
- Why is sizeof(string) == 32?
事实上,golang 的 strings.Builder
最接近 C++ 的 std::string
,其大小为 32 字节。参见 demo
我想了解使用 make([]int, 0)
创建空切片时会发生什么。我执行此代码进行测试:
emptySlice := make([]int, 0)
fmt.Println(len(emptySlice))
fmt.Println(cap(emptySlice))
fmt.Println(unsafe.Sizeof(emptySlice))
大小和容量return很明显,都是0,但是slice的大小是24字节,为什么?
24 字节应该是 3 int64
对吧?一个 24 字节的切片的内部数组应该是这样的:[3]int{}
,那么为什么一个空切片有 24 个字节?
Go 中的所有数据类型都是静态大小的。由于切片的动态特性,元素的数量与类型没有任何关联。
如果您阅读 unsafe.Sizeof
的 documentation,它会解释这里发生的事情:
The size does not include any memory possibly referenced by x. For instance, if x is a slice, Sizeof returns the size of the slice descriptor, not the size of the memory referenced by the slice.
unsafe.Sizeof
是对象在内存中的大小,和C、C++中的sizeof
完全一样。参见 How to get memory size of variable?
切片有大小,但也有调整大小的能力,所以最大调整大小的能力也必须存储在某处。但是可调整大小也意味着它不能是静态数组,而是需要存储指向其他(可能是动态分配的)数组的指针
整个事情意味着它需要存储它的 { begin, end, last valid index } or {开始,大小,容量}。这是一个包含 3 个值的元组,这意味着它在 64 位平台上的内存表示至少为 3×8 字节,除非您想将最大大小和容量限制为远小于 264字节
在许多具有相同动态大小调整功能的 C++ 类型中情况完全相同,例如 std::string
或 std::vector
也是 24 字节类型,尽管在某些实现中添加了 8 字节的填充对齐的原因,导致了一个 32 字节的字符串类型。参见
- Why is sizeof(string) == 32?
事实上,golang 的 strings.Builder
最接近 C++ 的 std::string
,其大小为 32 字节。参见 demo