Go でスライスからコピーするときにメモリ アドレスを再利用する
Go で範囲を使用してスライスから値をコピーするという奇妙な動作が発生しました。ループの結果、出力内のメモリ アドレスが重複しました。これを解決するには、コードを変更して一時変数を作成し、予期した個別のアドレスを生成しました。
この現象が発生するのは、元のコードでは、ループ変数 item がスライスの現在の要素へのポインタであるためです。 。スライスを反復処理すると、Go はこのポインター変数を再利用し、反復ごとに値を変更しますが、同じメモリ アドレスを維持します。その結果、&item を出力スライスに割り当てると、同じメモリ アドレスを誤って複数回複製することになります。
この再利用を防ぐために、変更されたコードは、現在の要素のコピーを保持する一時変数 i を作成します。これにより、Go は反復ごとに新しいメモリ割り当てを作成することになり、出力スライス内に一意のアドレスが生成されます。
この概念を説明するために、次の例を考えてみましょう。
package main import "fmt" type Region struct { Name string } func main() { // Create a slice of Region objects. regions := []Region{ {Name: "Central"}, {Name: "East"}, } // Original code - duplicates memory addresses fmt.Println("Original Code:") models1 := make([]Model, len(regions)) for idx, item := range regions { models1[idx] = &item } for _, m := range models1 { fmt.Println(m) } // Modified code - generates unique memory addresses fmt.Println("Modified Code:") models2 := make([]Model, len(regions)) for idx, _ := range regions { i := regions[idx] models2[idx] = &i } for _, m := range models2 { fmt.Println(m) } }
このコードの実行元のコードでは重複したメモリ アドレスが出力されるのに対し、変更されたコードでは一意のアドレスが生成されることがわかります。
以上が範囲ループを使用して Go スライスからコピーするとメモリ アドレスが重複する場合があるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。