这是一个非常直截了当的问题:
如果可以超过Golang中切片的容量,为什么首先会有容量参数?
我认为这与内存管理有关,某种"知道在内存中分配切片的位置",但我不确切知道.
如果可以超过Golang中切片的容量,为什么首先会有容量参数?
我不知道你的意思,但不能超过容量.切片可以索引到其长度(不包括),其长度不能超过容量,并且可以将切片重新切片到其容量(包括).
表单的主要表达方式
a[x]如果
a不是地图:...该指数x是在范围内,如果0 <= x < len(a),否则就超出了范围
......主要表达方式:
a[low : high]对于数组或字符串,该指数是在范围内,如果
0 <= low <= high <= len(a),否则它们是超出范围.对于切片,上部索引边界是切片容量cap(a)而不是长度.
并且:
......主要表达方式:
a[low : high : max]该指数是在范围内,如果
0 <= low <= high <= max <= cap(a),否则他们是超出范围.
您可以提供内置make()思考未来增长的能力,因此如果您需要向其添加元素或者需要重新分配它,则需要更少的分配.如果内置append()函数具有足够的容量用于附加元素,则内置函数只会复制您附加的切片,但如果它没有新元素的空间,则必须分配新的后备数组(并将现有内容复制到其中).append()将返回可能会或可能不会指向原始后备阵列的新切片.
我们来看一个例子吧.让我们创建一个0长度和容量的切片,并向其追加10个元素.要查看新的重新分配何时发生,我们还会打印其第一个元素的地址(第0个元素):
fmt.Println("With 0 capacity")
s := make([]int, 0)
for i := 0; i < 10; i++ {
s = append(s, i)
fmt.Println(i, &s[0])
}
Run Code Online (Sandbox Code Playgroud)
这输出:
With 0 capacity
0 0x416030
1 0x416030
2 0x416040
3 0x416040
4 0x452000
5 0x452000
6 0x452000
7 0x452000
8 0x434080
9 0x434080
Run Code Online (Sandbox Code Playgroud)
如您所见,当我们附加第三个(i=2),第五个(i=4)和第九个元素(i=8)时,以及当我们附加第一个元素时(因为原始后备数组不能保存任何元素),会分配一个新的后备数组.
现在让我们重复上面的例子,当我们再次创建长度= 0但容量= 10的初始切片时:
fmt.Println("With 10 capacity")
s = make([]int, 0, 10)
for i := 0; i < 10; i++ {
s = append(s, i)
fmt.Println(i, &s[0])
}
Run Code Online (Sandbox Code Playgroud)
现在输出将是:
With 10 capacity
0 0x44c030
1 0x44c030
2 0x44c030
3 0x44c030
4 0x44c030
5 0x44c030
6 0x44c030
7 0x44c030
8 0x44c030
9 0x44c030
Run Code Online (Sandbox Code Playgroud)
如您所见,第一个元素的地址从未改变,这意味着后台没有发生新的后备阵列分配.
试试Go Playground上的例子.