Go言語:スライス
スライスの話(go-tourは、なぜかArrayをとばしてSliceの話をする)
SliceとArrayは異なる。こちらを参照してお勉強。
あとはこちらのSlideShareを参照する。
Array
- Go言語のArrayは長さと要素の型を明らかにしたもの
- Arrayの初期化は構造体とだいたい同じ。
Slice
- Arrayの抽象的なもの(らしい)(抽象的とは?)
- Go言語ではArrayはあまり使われずに、Sliceが使われる。
- Sliceは、Arrayへのポインターと長さと容量で構成される。
- Sliceの初期化は、Arrayのそれとだいたい同じ。
[]型{ 初期化する値 }
- 要素数がいらない。
...
も書かない。
- 初期化時に値が渡されない場合、nilになる。
- 初期化の文法を使わずに、
make
関数を使うことでも作成可能。make([]T, len, cap)
cap
を省略した場合は、len == cap
になる。cap
がlen
よりも短い場合、エラーする。len
で指定された長さ分(0からlen
個分)の要素がzero valueで初期化される。
len
以内の要素の操作slice[2]
、slice[1] = 2
のように操作可能。- 代入は(当然ながら)破壊的。
len
を超える要素(というかインデックス)の操作slice[5]
のような操作をするとpanic。- 要素を追加するには、
append
を使う。 append( slice, T... ) []T
append
は破壊的ではない。- `容量を超える量を追加しようとすると、自動的に容量を追加してくれる。
- 再スライス可能。
- 部分的に取り出して、別のスライスにする。
- 配列部分はポインターなので、別のスライスになっても、同じメモリ領域をみている。
- スライスのインデックスの取り出し方。
slice[ : ]
-> すべての要素のスライス。slice[ lo:hi ] ->
lo番目から
hi - 1`番目の要素のスライス。slice[ lo: ]
->lo
番目以降の要素のスライス。slice[ :hi ]
->hi - 1
番目までの要素のスライス。
- 要素を削除する関数は用意されていない。
Array
以下の様な感じ。
func main() { ary1 := [3]string{ "dog", "cat" } fmt.Println( ary1 ) fmt.Println( ary1[0] ) fmt.Println( ary1[1] ) fmt.Println( ary1[2] ) ary2 := [3]int{ 10, 20 } fmt.Println( ary2 ) fmt.Println( ary2[0] ) fmt.Println( ary2[1] ) fmt.Println( ary2[2] ) // fmt.Println( ary2[3] ) } //=> // [dog cat ] // dog // cat // // [10 20 0] // 10 // 20 // 0
コメントアウトしている行を解くと、
invalid array index 3 (out of bounds for 3-element array) [process exited with non-zero status]
slice
基本的な操作を試してみる。
func main() { var sl0 []int fmt.Println( sl0 ) fmt.Println( len( sl0 ) ) fmt.Println( cap( sl0 ) ) sl1 := make([]int, 5) fmt.Println( sl1 ) fmt.Println( len( sl1 ) ) fmt.Println( cap( sl1 ) ) sl2 := make([]int, 5, 8 ) fmt.Println( sl2 ) fmt.Println( len( sl2 ) ) fmt.Println( cap( sl2 ) ) sl2[4] = 1 fmt.Println( sl2 ) fmt.Println( sl2[4] ) // fmt.Println( sl2[5] ) sl3 := append( sl2, 3, 4, 5, 6 ) fmt.Println( sl2 ) fmt.Println( len( sl2 ) ) fmt.Println( cap( sl2 ) ) fmt.Println( sl3 ) fmt.Println( len( sl3 ) ) fmt.Println( cap( sl3 ) ) } //=> // [] // 0 // 0 // [0 0 0 0 0] // 5 // 5 // [0 0 0 0 0] // 5 // 8 // [0 0 0 0 1] // 1 // [0 0 0 0 1] // 5 // 8 // [0 0 0 0 1 3 4 5 6] // 9 // 16
コメントアウトしている行を解くと、
panic: runtime error: index out of range [process exited with non-zero status]
slicing slices
[10 20 30 40 50 60 70 80 90] [40 50 60 70] [60 70 80 90] [40 50 60] [10 20 30 40 51 60 70 80 90] [40 51 60 70] [60 70 80 90] [40 51 60] [10 20 30 40 52 60 70 80 90] [40 52 60 70] [60 70 80 90] [40 52 60]