golang中的cap vs len

Ali*_*avi 26 go slice

golang中一个切片的cap和len有什么区别?

根据定义:

切片具有长度和容量.

切片的长度是它包含的元素数.

切片的容量是基础数组中元素的数量,从切片中的第一个元素开始计算.

x := make([]int, 0, 5) // len(b)=0, cap(b)=5
Run Code Online (Sandbox Code Playgroud)

len是否仅表示非空值?

jma*_*ney 61

切片是一种在封面下使用数组的抽象.

cap告诉你底层数组的容量.len告诉你数组中有多少项.

Go中的切片抽象非常好,因为它会为您调整底层数组的大小,而且Go数组中的大小不能调整大小,因此几乎总是使用切片.

例:

s := make([]int, 0, 3)
for i := 0; i < 5; i++ {
    s = append(s, i)
    fmt.Printf("cap %v, len %v, %p\n", cap(s), len(s), s)
}
Run Code Online (Sandbox Code Playgroud)

会输出这样的东西:

cap 3, len 1, 0x1040e130
cap 3, len 2, 0x1040e130
cap 3, len 3, 0x1040e130
cap 8, len 4, 0x10432220
cap 8, len 5, 0x10432220
Run Code Online (Sandbox Code Playgroud)

正如您所看到的那样,只要满足容量,append就会返回一个容量更大的新切片.在第4次迭代中,您将注意到更大的容量和新的指针地址.

播放示例

我意识到你没有问过数组和追加,但它们在理解切片和内置的原因方面非常基础.

  • 与切片不同的@BradEllis数组没有nil值.当你创建一个数组`var array [3] int`时,你明确地分配了一个数组的容量和长度.在谈到Go中的数组时,cap和len函数是相同的.您需要记住Go中的切片是一种利用数组但不是数组的数据类型.因此,当你调用`cap(someSlice)`时,你正在检查下划线数组的容量或长度,但当你调用`len(someSlice)时,你正在检查你明确添加到切片中的项数.例如:https://play.golang.org/p/ahlHLkD4_Wt (3认同)
  • 当达到上限时,go 会将“上限”加倍..为什么?这是一件好事吗...例如添加“769”项数组上限将为“1536” (3认同)
  • 好答案。OP可能不再关心,但我可以看到这对很多可能会发现它的人有所帮助。 (2认同)
  • @RandyHoward谢谢,我很感激.我发现知道指针地址变得非常重要. (2认同)
  • @j马洛尼。这非常有帮助。我仍然难以理解的一件事是数组和切片的 nil 值为零(不是 nil 或 null),所以长度实际上如何与容量不同。容量为 3 的切片中的每个元素在第一次迭代中不应该具有 {1,0,0} ...让 len 为 3 而不是 1 吗?我的意思是,如果这只是惯例,我不明白该惯例中的逻辑。我只是错过了一些东西还是我应该按原样接受它? (2认同)

Tyl*_*ler 7

源代码

// The len built-in function returns the length of v, according to its type:
//  Array: the number of elements in v.
//  Pointer to array: the number of elements in *v (even if v is nil).
//  Slice, or map: the number of elements in v; if v is nil, len(v) is zero.
//  String: the number of bytes in v.
//  Channel: the number of elements queued (unread) in the channel buffer;
//  if v is nil, len(v) is zero.
func len(v Type) int

// The cap built-in function returns the capacity of v, according to its type:
//  Array: the number of elements in v (same as len(v)).
//  Pointer to array: the number of elements in *v (same as len(v)).
//  Slice: the maximum length the slice can reach when resliced;
//  if v is nil, cap(v) is zero.
//  Channel: the channel buffer capacity, in units of elements;
//  if v is nil, cap(v) is zero.
func cap(v Type) int
Run Code Online (Sandbox Code Playgroud)