我最近拿起了Go,现在我对以下代码感到困惑:
package main
import "fmt"
func main() {
a := make([]int, 5)
printSlice("a", a)
b := make([]int, 0, 5)
printSlice("b", b)
c := b[:2]
printSlice("c", c)
d := c[2:5]
printSlice("d", d)
}
func printSlice(s string, x []int) {
fmt.Printf("%s len=%d cap=%d %v\n",
s, len(x), cap(x), x)
}
Run Code Online (Sandbox Code Playgroud)
结果如下:
a len=5 cap=5 [0 0 0 0 0]
b len=0 cap=5 []
c len=2 cap=5 [0 0] //why the capacity of c not 2 but 5 instead
d len=3 cap=3 [0 0 0]
Run Code Online (Sandbox Code Playgroud)
任何帮助都会谢谢.
Den*_*ret 22
c是从数组中取出的切片b.这不是一个副本,而只是一个窗口超过2个第一个元素b.
由于b容量为5,c可以扩展到其他3个地方(实际上它创建了一个新的切片但在内存中的相同位置).
切片的最大容量是底层数组的容量减去数组中切片起始位置:
array : [0 0 0 0 0 0 0 0 0 0 0 0]
array : <---- capacity --->
slice : [0 0 0 0]
slice : <---- capacity --->
Run Code Online (Sandbox Code Playgroud)
也许这个程序会更清楚地表明c和d只是b上的窗口:
func main() {
b := make([]int, 0, 5)
c := b[:2]
d := c[1:5] // this is equivalent to d := b[1:5]
d[0] = 1
printSlice("c", c)
printSlice("d", d)
}
Run Code Online (Sandbox Code Playgroud)
输出:
c len=2 cap=5 [0 1] // modifying d has modified c
d len=4 cap=4 [1 0 0 0]
Run Code Online (Sandbox Code Playgroud)
Von*_*onC 17
请注意,在第1.2版(2013年第4季度,1.2rc1现在可用)中,您可以将切片与其自身的容量相关联(而不是从基础数组推断出的容量).
切片操作通过描述已创建的数组或切片的连续部分来创建新切片:
var array [10]int
slice := array[2:4]
Run Code Online (Sandbox Code Playgroud)
切片的容量是切片可以保持的最大元素数,即使在重新切换之后也是如此; 它反映了底层数组的大小.
在此示例中,slice变量的容量为8.
(基础数组的容量减去数组中切片起始位置)
array : [0 0 0 0 0 0 0 0 0 0]
array : <---- capacity --->
slice : [0 0]
slice : <-- capacity --> 8 (10-2)
Run Code Online (Sandbox Code Playgroud)
Go 1.2添加了新语法,允许切片操作指定容量和长度.
第二个冒号引入容量值,该值必须小于或等于源切片或阵列的容量,并根据原点进行调整.例如,
slice = array[2:4:6]
array : [0 0 0 0 0 0 0 0 0 0]
array : <---- capacity ---> 10
slice : [0 0]
slice : <- cap-> 4 (6-2)
Run Code Online (Sandbox Code Playgroud)
将切片设置为与前面示例中的长度相同,但其容量现在只有4个元素(6-2).
无法使用此新切片值来访问原始数组的最后两个元素.
主要论点是让程序员更多地控制append.
a[i : j : k]
Run Code Online (Sandbox Code Playgroud)
那片有:
j - ik - i如果i <= j <= k <= cap(a)不是这样,评估就会引起恐慌.