Go では、スライスは反復可能な強力なデータ構造です。 range キーワードを使用する必要はありません。ただし、特殊な現象として、for-range を使用して構造体のスライスを反復処理すると、結果のマップ内の要素が同じアドレスを共有します。この動作は、特に元のスライス内の要素が一意のアドレスを持つ必要があるため、混乱を招く可能性があります。
この現象を理解する鍵は、変数の仕組みにあります。メモリに保存されます。 for-range ループ (この場合は stu) 内のスライスの要素にアクセスすると、ローカル変数 stu は構造体のコピーを保持します。ポインタをローカル変数に割り当てると、マップ内のすべての要素がメモリ内の構造体の同じコピーを指すようになります。
この問題を解決するには、スライス要素のアドレスを割り当てるには、スライス要素自体のアドレスを取得するようにコードを変更する必要があります。 stu の代わりに s[i] を使用すると、スライス内の実際の要素へのポインタがマップに割り当てられます。
package main import "fmt" type student struct { Name string Age int } func main() { m := make(map[string]*student) s := []student{ {Name: "Allen", Age: 24}, {Name: "Tom", Age: 23}, } for i := range s { m[s[i].Name] = &s[i] // Change here } fmt.Println(m) for key, value := range m { fmt.Println(key, value) } }
出力:
map[Allen:0xc0000a6058 Tom:0xc0000a6060] Allen &{Allen 24} Tom &{Tom 23}
根底にあるメモリ管理の動作を理解することで、このスライス範囲の現象に対処できます。 行く。スライス要素自体のアドレスを取得することで、マップ内の各要素がメモリ内の一意の構造体を指していることを確認し、データの整合性を維持します。
以上が構造体のマッピング時に Go Slice Range ループで共有アドレスが作成されるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。