ホームページ >バックエンド開発 >Golang >Go でスライス範囲を反復すると、アドレスではなくコピーが返される場合があるのはなぜですか?

Go でスライス範囲を反復すると、アドレスではなくコピーが返される場合があるのはなぜですか?

DDD
DDDオリジナル
2024-12-05 15:54:14205ブラウズ

Why Do Slice Range Iterations in Go Sometimes Return Copies Instead of Addresses?

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

Go では、スライス範囲の動作がわかりにくい場合があります。 range 句を使用してスライスを反復処理する場合、反復変数が各要素のアドレスを保持していると信じてしまいがちです。ただし、常にそうとは限りません。そのようなシナリオの 1 つは、構造体とマップを操作する場合です。

次のコードを考えてみましょう:

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 _, stu := range s {
        m[stu.Name] = &stu
    }
}

このコードは、構造体のスライスを反復処理し、キーと値のペアをマップに追加します。各構造体を取得し、その構造体のアドレスを値として格納します。ただし、結果のマップは、すべての値が同じアドレスを指していることを示しています。

この現象を説明するには、スライス範囲の基礎となる実装を確認する必要があります。 range 句を使用してスライスが反復されると、反復変数はスライスから要素のコピーを受け取ります。したがって、反復変数は、構造体のアドレスではなく、構造体のコピーを保持します。

この問題を修正して構造体のアドレスをマップに保存するには、スライス要素のアドレスを取得するようにコードを変更する必要があります。 :

for i := range s {
    m[s[i].Name] = &s[i]
}

この変更により、反復変数が構造体のアドレスを保持し、マップがスライス内の各構造体のアドレスを正しく格納するようになります。

以上がGo でスライス範囲を反復すると、アドレスではなくコピーが返される場合があるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。