Go言語 スライス #12

Go言語の配列は要素数を増やせませんが「スライス」を使えば増やせます。

まずは配列の定義の復習とスライスの定義を見ます。

The Go Playground で実行する

配列は[数字]intまたは[…]intと書きますが、スライスは[]intというように書きます。

スライスに要素を追加したい場合は組み込み関数appendを使う

スライスはappend関数でサイズを増やせます(要素数を増やせます)。

The Go Playground で実行する

スライスは参照

配列とスライスの大きな違いは上記の通りサイズを増やせるかどうかですが、他にも違いがありまして、それはスライスは参照であるということです。
参照の意味を理解するのは難しいですが、下の例を見ていただくと多少わかりやすいかも知れません。

The Go Playground で実行する

参照とは同じメモリアドレスを参照しているということです。

変数はメモリ上に確保された領域(メモリアドレス)で、そこに値を格納しています。

配列の場合、以下の代入でa2にaのコピーが渡ります。
a2 := a
a2は、aとは違うメモリアドレスで、そこにaの値がコピーされています。
a2を変更してもaには影響出ません。

スライスの場合、以下の代入でs2にsの参照しているメモリアドレスが渡ります。
s2 := s
sとs2は同じメモリアドレスを参照しているので、s2を変更したらsも変わります。

それではスライスの値はどこに保存されているのでしょうか?

それは、見えないところで配列が作られていてそこに値があるわけです。

スライスを作ると裏で配列が作られ、スライスはそのメモリアドレスを保持している。

他の言語で言うところのスライス

Pythonなどの他の言語でスライスと言えば、シーケンス(順番に処理するためのデータ構造で文字列や配列など)要素の一部分を取り出すための構文という意味で使われますが、Go言語ではそれもスライスと呼んだりスライシングと呼んだりしていますが、ここでは混同しないようにスライシングと言います。
配列をスライシングしてスライスを作る例です。
なお変数にアンド(&付き変数)をつけるとメモリアドレスが表示されます。

The Go Playground で実行する

appendでaのサイズを増やした後は違うメモリアドレスになっています。
ここでは裏で新しい配列が作られて、そのメモリアドレスを参照しています。

makeでスライスを作成

あらかじめ長さと容量を決めて空のスライスを作成したい場合はmake関数を使います。
s := make([]int, length, capacity)
make関数の第1引数([]int)がスライスの型、第2引数(length)がスライスの長さ、第3引数(capacity)が(スライスの裏で作成される配列の長さ)容量です。
容量は省略可能で、省略した場合長さ=容量になります。
容量はcap()という関数でも知ることが出来ます。

The Go Playground で実行する

appendでスライスの長さが多くなり、それが容量を超えた場合、容量が倍になって新しい配列が裏にできて、スライスはそれを参照するようになります。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする