Golangのスライスと配列のメモ
golangの配列はC/C++の配列に相当し、固定サイズで、動的にサイズを拡張できないが、スライスはC++のVectorに相当し、動的にサイズを拡張することができ、サイズが容量を超えた場合、メモリを再割り当てし、データを新しいメモリ領域にコピーすることができる.
既存の配列に基づいてスライスを定義する例を次に示します.
[6 7 8 1 2 3 4 5 6] [6 7 8 9 10] [1 2 3 4 5 6 7 8 9 10]
この結果,s 1は新たに6つの要素を追加した後,既存の容量を超えたため,メモリを再割り当てし,新しいデータを挿入しなければならず,このときs 1に対応する下位配列はa 1ではなく,システム自身が新たな配列を生産した.
このときs 2に対応する下位配列は依然としてa 1であるため,s 2におけるデータは変化しない.
次の例を見てみましょう.
[6 7 8 1 2] [6 7 8 1 2] [1 2 3 4 5 6 7 8 1 2]
このとき、s 1に新たに追加された要素の個数がs 1の現在の容量を超えていないため、s 1は新たにメモリを開いておらず、a 1配列のメモリを使っているため、s 1の変更によりa 1配列の値が変更された.
これは興味深い問題で,スライスしたappend関数を用いると,既存の配列の既存の要素の変化をもたらす......
だから配列とスライスを混ぜて使うときは、気をつけなければならないと思います.
テストプログラムで使用されるgoバージョンは1.1です.具体的なバージョンは:
go version go1.1 linux/amd64
既存の配列に基づいてスライスを定義する例を次に示します.
package main
import (
"fmt"
)
func main(){
a1:=[10]int{1,2,3,4,5,6,7,8,9,10}
s1:=a1[5:8] // s1 5
s2:=a1[5:10] // s2 5
s1 = append(s1, 1,2,3,4,5,6)
fmt.Println(s1)
fmt.Println(s2)
fmt.Println(a1)
}
のコード出力結果は、次のとおりです.[6 7 8 1 2 3 4 5 6] [6 7 8 9 10] [1 2 3 4 5 6 7 8 9 10]
この結果,s 1は新たに6つの要素を追加した後,既存の容量を超えたため,メモリを再割り当てし,新しいデータを挿入しなければならず,このときs 1に対応する下位配列はa 1ではなく,システム自身が新たな配列を生産した.
このときs 2に対応する下位配列は依然としてa 1であるため,s 2におけるデータは変化しない.
次の例を見てみましょう.
package main
import (
"fmt"
)
func main(){
a1:=[10]int{1,2,3,4,5,6,7,8,9,10}
s1:=a1[5:8] // s1 5
s2:=a1[5:10] // s2 5
s1 = append(s1,1,2)
fmt.Println(s1)
fmt.Println(s2)
fmt.Println(a1)
}
今回の出力結果はどうなると思いますか?結果は次のとおりです.[6 7 8 1 2] [6 7 8 1 2] [1 2 3 4 5 6 7 8 1 2]
このとき、s 1に新たに追加された要素の個数がs 1の現在の容量を超えていないため、s 1は新たにメモリを開いておらず、a 1配列のメモリを使っているため、s 1の変更によりa 1配列の値が変更された.
これは興味深い問題で,スライスしたappend関数を用いると,既存の配列の既存の要素の変化をもたらす......
だから配列とスライスを混ぜて使うときは、気をつけなければならないと思います.
テストプログラムで使用されるgoバージョンは1.1です.具体的なバージョンは:
go version go1.1 linux/amd64