golang 中的 cap vs len 或 slice
cap vs len of slice in golang
golang中切片的cap和len有什么区别?
根据定义:
切片既有长度又有容量。
切片的长度是它包含的元素数。
切片的容量是底层数组中元素的数量,从切片中的第一个元素开始计算。
x := make([]int, 0, 5) // len(b)=0, cap(b)=5
len 是否仅表示非空值?
您已经回答了您的问题 - 切片中基础数组的长度不一定与数组包含的元素数相同。
来自source code:
// 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
切片是一种在幕后使用数组的抽象。
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)
}
将输出如下内容:
cap 3, len 1, 0x1040e130
cap 3, len 2, 0x1040e130
cap 3, len 3, 0x1040e130
cap 6, len 4, 0x10432220
cap 6, len 5, 0x10432220
如您所见,一旦满足容量,append
将 return 一个容量更大的新切片。在第 4 次迭代中,您会注意到更大的容量和新的指针地址。
我知道你没有问过数组和追加,但它们对于理解切片和内置函数的原因来说是非常基础的。
简单说明
切片是数组的自增长形式,因此有两个主要属性。
长度是切片拥有的 elements() 总数,可用于循环遍历我们存储在切片中的元素。此外,当我们打印切片时,所有元素直到长度被打印出来。
容量是底层数组中没有元素的总数,当你追加更多元素时,长度会增加直到容量。之后,任何进一步附加到 slice 都会导致容量自动增加(大约双倍)和长度增加没有附加的元素。
当您从所有实际 read/write 发生在底层数组上的切片中切出子切片时,真正的魔法就会发生。因此,子切片中的任何更改也会更改原始切片和基础数组中的数据。因为任何子切片都可以有自己的长度和容量。
仔细阅读下面的程序。 golang游记其修改版
package main
import "fmt"
func main() {
sorig := []int{2, 3, 5, 7, 11, 13}
printSlice(sorig)
// Slice the slice to give it zero length.
s := sorig[:0]
printSlice(s)
// Extend its length.
s = s[:4]
s[2] = 555
printSlice(s)
// Drop its first two values.
s = s[2:]
printSlice(s)
printSlice(sorig)
}
func printSlice(s []int) {
fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
//Output
//len=6 cap=6 [2 3 5 7 11 13]
//len=0 cap=6 []
//len=4 cap=6 [2 3 555 7]
//len=2 cap=4 [555 7]
//len=6 cap=6 [2 3 555 7 11 13]
golang中切片的cap和len有什么区别?
根据定义:
切片既有长度又有容量。
切片的长度是它包含的元素数。
切片的容量是底层数组中元素的数量,从切片中的第一个元素开始计算。
x := make([]int, 0, 5) // len(b)=0, cap(b)=5
len 是否仅表示非空值?
您已经回答了您的问题 - 切片中基础数组的长度不一定与数组包含的元素数相同。
来自source code:
// 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
切片是一种在幕后使用数组的抽象。
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)
}
将输出如下内容:
cap 3, len 1, 0x1040e130
cap 3, len 2, 0x1040e130
cap 3, len 3, 0x1040e130
cap 6, len 4, 0x10432220
cap 6, len 5, 0x10432220
如您所见,一旦满足容量,append
将 return 一个容量更大的新切片。在第 4 次迭代中,您会注意到更大的容量和新的指针地址。
我知道你没有问过数组和追加,但它们对于理解切片和内置函数的原因来说是非常基础的。
简单说明 切片是数组的自增长形式,因此有两个主要属性。
长度是切片拥有的 elements() 总数,可用于循环遍历我们存储在切片中的元素。此外,当我们打印切片时,所有元素直到长度被打印出来。
容量是底层数组中没有元素的总数,当你追加更多元素时,长度会增加直到容量。之后,任何进一步附加到 slice 都会导致容量自动增加(大约双倍)和长度增加没有附加的元素。
当您从所有实际 read/write 发生在底层数组上的切片中切出子切片时,真正的魔法就会发生。因此,子切片中的任何更改也会更改原始切片和基础数组中的数据。因为任何子切片都可以有自己的长度和容量。
仔细阅读下面的程序。 golang游记其修改版
package main
import "fmt"
func main() {
sorig := []int{2, 3, 5, 7, 11, 13}
printSlice(sorig)
// Slice the slice to give it zero length.
s := sorig[:0]
printSlice(s)
// Extend its length.
s = s[:4]
s[2] = 555
printSlice(s)
// Drop its first two values.
s = s[2:]
printSlice(s)
printSlice(sorig)
}
func printSlice(s []int) {
fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
//Output
//len=6 cap=6 [2 3 5 7 11 13]
//len=0 cap=6 []
//len=4 cap=6 [2 3 555 7]
//len=2 cap=4 [555 7]
//len=6 cap=6 [2 3 555 7 11 13]