Goのsliceでappendした場合同じ添え字でのポインタでも違う値になる気がしたので確認する
- Goのsliceは配列の要素の部分列へアクセスする為のデータ構造
- この要素となる配列を基底配列という
構造として、ポインタ、長さ、容量を持っている
この基底配列へアクセスする為には
refrection
を使用する
基本的なこと
配列の宣言
a := [...]int{1,2,3}
package main import ( "fmt" "reflect" ) func main() { a := [...]int{1,2,3} fmt.Println(reflect.TypeOf(a)) }
データ型を確認すると
[3]int
Slice宣言
a := []int{1,2,3}
package main import ( "fmt" "reflect" ) func main() { s := []int{1,2,3} fmt.Println(reflect.TypeOf(s)) }
データ型を確認すると
[]int
配列からSliceを生成
- 宣言した配列aからsliceを生成する
package main import ( "fmt" "reflect" ) func main() { a := [...]int{1,2,3} s := a[0:1] fmt.Printf("%v\n", &a[0]) fmt.Printf("%v\n", &s[0]) }
- 配列の先頭とSliceの先頭は同じ物を指している
0xc000016140 0xc000016140
sliceを拡張する
- appendを使用してsliceを拡張する
package main import ( "fmt" ) func main() { a := [...]int{1, 2, 3} s := a[0:1] fmt.Printf("a[0] address: %v\n", &a[0]) fmt.Printf("s[0] address: %v\n", &s[0]) fmt.Printf("slice: %v\n", s) fmt.Printf("cap: %d\n", cap(s)) fmt.Printf("len: %d\n", len(s)) fmt.Printf("s[0] address: %v\n", &s[0]) s = append(s, 4) fmt.Printf("slice: %v\n", s) fmt.Printf("cap: %d\n", cap(s)) fmt.Printf("len: %d\n", len(s)) fmt.Printf("s[0] address: %v\n", &s[0]) s = append(s, 5) fmt.Printf("slice: %v\n", s) fmt.Printf("cap: %d\n", cap(s)) fmt.Printf("len: %d\n", len(s)) fmt.Printf("s[0] address: %v\n", &s[0]) s = append(s, 6) fmt.Printf("slice: %v\n", s) fmt.Printf("cap: %d\n", cap(s)) fmt.Printf("len: %d\n", len(s)) fmt.Printf("s[0] address: %v\n", &s[0]) }
- 拡張した場合sliceのsize(cap)を超えた場合
- 参照先のアドレスが変わっていることが分かる
a[0] address: 0xc000084000 s[0] address: 0xc000084000 slice: [1] cap: 3 len: 1 s[0] address: 0xc000084000 slice: [1 4] cap: 3 len: 2 s[0] address: 0xc000084000 slice: [1 4 5] cap: 3 len: 3 s[0] address: 0xc000084000 slice: [1 4 5 6] cap: 6 len: 4 s[0] address: 0xc000064030
基底配列が見えない場合はこれが分かりづらくなる。
参考文献
プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)
- 作者: Alan A.A. Donovan,Brian W. Kernighan,柴田芳樹
- 出版社/メーカー: 丸善出版
- 発売日: 2016/06/20
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (2件) を見る