25

私は最近 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)
}

そして結果:

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]
4

2 に答える 2

29

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 ---> 

おそらく、このプログラムは、 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)
}

出力:

c len=2 cap=5 [0 1] // modifying d has modified c
d len=4 cap=4 [1 0 0 0] 
于 2012-10-07T12:19:46.673 に答える