ホームページ > バックエンド開発 > Golang > 構造体のマッピング時に Go Slice Range ループで共有アドレスが作成されるのはなぜですか?

構造体のマッピング時に Go Slice Range ループで共有アドレスが作成されるのはなぜですか?

Linda Hamilton
リリース: 2024-12-04 22:44:11
オリジナル
421 人が閲覧しました

Why Do Go Slice Range Loops Create Shared Addresses When Mapping Structs?

Go のスライス範囲現象を理解する

問題: 謎のスライス範囲の動作

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 サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート