英文:
Different sizes of arrays using make or default initialization
问题
我是你的中文翻译助手,以下是翻译好的内容:
我刚开始学习Go语言,想要理解这门语言以编写高效的代码。在下面的代码中,两个数组的大小相差140%,有人可以解释一下这是为什么吗?
package main
import (
"fmt"
"unsafe"
)
func main() {
ind1 := make([]bool, 10)
var ind2 [10]bool
fmt.Println(unsafe.Sizeof(ind1)) // 24
fmt.Println(len(ind1)) // 10
fmt.Println(unsafe.Sizeof(ind2)) // 10
fmt.Println(len(ind2)) // 10
}
第一个数组的大小仍然是10,即使容量被显式设置为:
ind1 := make([]bool, 10, 10)
有人可以解释一下这是为什么吗?在使用make
时是否有额外的开销?如果有,为什么推荐使用make
而不是默认初始化?
英文:
I'm new to Go and try to understand the language in order to write efficient code. In the following code, sizes of the two arrays differ by 140%, can someone explain this?
package main
import (
"fmt"
"unsafe"
)
func main() {
ind1 := make([]bool, 10)
var ind2 [10]bool
fmt.Println(unsafe.Sizeof(ind1)) // 24
fmt.Println(len(ind1)) // 10
fmt.Println(unsafe.Sizeof(ind2)) // 10
fmt.Println(len(ind2)) // 10
}
The size of the first array remains 10, even in case the capacity is set explicitly:
ind1 := make([]bool, 10, 10)
Can someone explain this? Is there any additional overhead in using make
? If yes, why is it recommended to use make over default initialization?
答案1
得分: 5
在Go语言中,数组(Arrays)和切片(Slices)是不同的概念。
你的ind1
是一个切片,而ind2
是一个数组。数组的长度是类型的一部分,所以例如[2]bool
和[3]bool
是两种不同的数组类型。
在Go语言中,切片是对底层数组的一个连续片段的描述符,并提供对该数组中一系列编号的元素的访问。切片头部是一个类似结构体的数据结构,由类型reflect.SliceHeader
表示:
type SliceHeader struct {
Data uintptr
Len int
Cap int
}
它包含一个数据指针(指向所表示片段的第一个元素)、长度和容量。
unsafe.SizeOf()
函数返回一个假设变量所占用的字节数。它不包括可能被该变量引用的任何内存。
因此,如果你传递一个切片值(ind1
),它将告诉你上述切片头部的大小。请注意,SliceHeader
的字段大小是与架构相关的,例如int
在一个平台上可能是4个字节,在另一个平台上可能是8个字节。大小24
适用于64位架构。
Go Playground运行在32位架构上。让我们看看这个例子:
fmt.Println(unsafe.Sizeof(make([]bool, 10)))
fmt.Println(unsafe.Sizeof(make([]bool, 20)))
fmt.Println(unsafe.Sizeof([10]bool{}))
fmt.Println(unsafe.Sizeof([20]bool{}))
输出结果(在Go Playground上尝试):
12
12
10
20
如你所见,无论你传递给unsafe.SizeOf()
的切片长度是多少,它在Go Playground上始终返回12(在64位架构上返回24)。
另一方面,数组值包含所有的元素,因此它的大小取决于它的长度。[10]bool
的大小是10,[20]bool
的大小是20。
请参阅相关问题和答案,了解更多关于切片、数组以及它们之间的差异和关系的信息:
必读的博文:
英文:
Arrays and slices in Go are different things.
Your ind1
is a slice, and ind2
is an array. The length of an array is part of the type, so for example [2]bool
and [3]bool
are 2 different array types.
A slice in Go is a descriptor for a contiguous segment of an underlying array and provides access to a numbered sequence of elements from that array. This slice header is a struct-like data structure represented by the type reflect.SliceHeader
:
type SliceHeader struct {
Data uintptr
Len int
Cap int
}
It contains a data pointer (to the first element of the represented segment), a length and a capacity.
The unsafe.SizeOf()
function returns the size in bytes of the hypothetical variable as if it would hold the passed value. It does not include any memory possibly referenced by it.
So if you pass a slice value (ind1
), it will tell you the size of the above mentioned slice header. Note that the size of the fields of SliceHeader
are architecture dependent, e.g. int
may be 4 bytes on one platform and it may be 8 bytes on another. The size 24
applies to 64-bit architectures.
The Go Playground runs on a 32-bit architecture. Let's see this example:
fmt.Println(unsafe.Sizeof(make([]bool, 10)))
fmt.Println(unsafe.Sizeof(make([]bool, 20)))
fmt.Println(unsafe.Sizeof([10]bool{}))
fmt.Println(unsafe.Sizeof([20]bool{}))
Output (try it on the Go Playground):
12
12
10
20
As you can see, no matter the length of the slice you pass to unsafe.SizeOf()
, it always returns 12 on the Go Playground (and 24 on 64-bit architectures).
On the other hand, an array value includes all its elements, and as such, its size depends on its length. Size of [10]bool
is 10, and size of [20]bool
is 20.
See related questions+answers to learn more about slices, arrays and the difference and relation between them:
https://stackoverflow.com/questions/38645175/why-have-arrays-in-go/38645895#38645895
https://stackoverflow.com/questions/30694652/why-use-arrays-instead-of-slices
Must read blog posts:
答案2
得分: 1
ind1
是一个切片(类型为 []bool
)。
ind2
是一个数组(类型为 [10]bool
)。
它们的类型不同。
unsafe.Sizeof(ind1)
的结果可能与传递给 make
的参数无关。
英文:
ind1
is a slice (the type is []bool
).
ind2
is an array (the type is [10]bool
).
They are not of the same type.
The result of unsafe.Sizeof(ind1)
probably has nothing to do with the arguments passed to make
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论