ここでは、Go言語のスライスについて、makeとcapを扱います。
スライスの作成についてはすでに見てきましたが、このスライスを作成するときに組み込み関数makeを使用して、スライスの大きさ(長さ)、キャパシティ(容量)を指定でして宣言することができます。
これを利用することによって、メモリ上の利点がありパフォーマンスを向上させることができるのですが、Go入門時点ではそこまで必要ないと思うので、こういうものがあるということだけ頭に入れておくことにします。
スライスとmake
スライスの定義には、make()を使うことが出来ます。メモリを割り当てる操作なので、パフォーマンスが向上するというメリットがあります。
makeは、次のような形でスライスを定義します。
make([]型名, length, capacity)
make()の中で、角括弧[]の後に型名を指定し、長さ、容量を指定してスライスを作ります。
具体的なコードで見て行きましょう。
package main
import "fmt"
func main() {
x := make([]int, 3, 5)
fmt.Println(x)
fmt.Println(len(x))
fmt.Println(cap(x))
x = append(x, 0, 0)
fmt.Println(x)
fmt.Println(len(x))
fmt.Println(cap(x))
x = append(x, 6, 7, 8, 9, 10)
fmt.Println(x)
fmt.Println(len(x))
fmt.Println(cap(x))
}
int型で、長さ3、容量5のスライスを定義しています。len()で長さを、cap()で容量を出力しています。
また、appendを使って0を2つ追加しています。これで容量が満たされることになります。
さらにそこからappendでデータを5つ追加しています。
実行するとこうなります。
[0 0 0]
3
5
[0 0 0 0 0]
5
5
[0 0 0 0 0 6 7 8 9 10]
10
10
capの値が最初に割り当てたものよりも増えていますが、これは制限の範囲を予め設けていたというのではなく、メモリの割り当て領域を確保している意味になります。
makeのcap
make()で長さを指定せずに容量(cap)のみを指定してスライスを作ると、0の要素を容量と同じ長さを持ったスライスを作成することができます。
make([]型名, capacity)
具体的なコードで見てみましょう。
package main
import "fmt"
func main() {
x := make([]int, 5)
fmt.Println(x)
fmt.Println(len(x))
fmt.Println(cap(x))
}
容量5のスライスを定義しています。
実行結果はこちらです。
[0 0 0 0 0]
5
5
長さが容量と同じで、要素の値が全て0であるのがわかります。
では、次のように容量を0にして定義するとどうでしょうか?
package main
import "fmt"
func main() {
x := make([]int, 0)
fmt.Println(x)
fmt.Println(len(x))
fmt.Println(cap(x))
var y []int
fmt.Println(y)
fmt.Println(len(y))
fmt.Println(cap(y))
}
上側はmakeを使って容量0のスライスを定義しています。下側は単に値を代入せずにスライスを宣言しています。
実行してみましょう。
[]
0
0
[]
0
0
どちらも同じ結果にはなっていますが、上側は0のスライスをメモリに割り当てていますが、下側はそういう意味合いはなく、nilを示しているという違いがあります。
最後に
ここでは、Go言語のスライスについてmakeを使った定義を扱いました。
makeを使ったスライスは、要素の長さと容量を指定して作ることが出来ます。
メモリの割り当てを伴ったスライス定義なので、パフォーマンス上のメリットがあるという面があります。ただし、このあたりの考えは上級者向けでしょう。