Golangのスライスと配列のメモ


golangの配列はC/C++の配列に相当し、固定サイズで、動的にサイズを拡張できないが、スライスはC++のVectorに相当し、動的にサイズを拡張することができ、サイズが容量を超えた場合、メモリを再割り当てし、データを新しいメモリ領域にコピーすることができる.
既存の配列に基づいてスライスを定義する例を次に示します.
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