Golang スライスからコピーするときのメモリ アドレスの再利用
Go プログラミングでよくある誤解は、スライスからのメモリ アドレスのコピーに関するものです。次の状況を考えてみましょう:
Model インターフェイスと、それを実装する Regional struct があります。インターフェイスは、Region 構造体のポインタに実装されます。また、Region オブジェクトのスライスである Regionals コレクションもあります。 Regionals オブジェクトを []Model に変換するメソッドがあります:
// Regions is the collection of the Region model type Regions []Region // Returns the model collection as a list of models func (coll *Regions) ToModelList() []Model { output := make([]Model, len(*coll)) for idx, item := range *coll { output[idx] = &item } return output }
このコードを実行すると、出力スライス内のモデルごとに個別のアドレスが取得されることが期待されます。ただし、リージョンへの最初のポインターが複数回出力されることになります。
この問題を解決するには、元のメソッドのループ変数項目を検討してください。これはループのすべての反復で同じであるため、結果のスライスには同じ基になるデータへの参照が含まれます。
一方、実用的なソリューションでは、 i := (*coll)[idx] を使用して反復ごとに新しい変数を作成します。これにより、出力スライス内の各モデルが一意のメモリ アドレスを持つことが保証されます。
よりよく理解するには、次のコード スニペットを検討してください。
func main() { coll := []int{5, 10, 15} for i, v := range coll { fmt.Printf("This one is always the same; %v\n", &v) fmt.Println("This one is 4 bytes larger each iteration; %v\n", &coll[i]) } }
このコードは、v のメモリ アドレスがcoll[i] のメモリ アドレスはループ全体で同じままですが、反復ごとに増加します。この動作は、v がループ変数であり、定数のままであるのに対し、coll[i] は反復ごとに新しい変数であるためです。
以上がGo スライスからコピーするとメモリ アドレスが再利用されるのはなぜですか?それを修正するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。