ホームページ > バックエンド開発 > Golang > Go の「range」関数がメモリ アドレスを再利用するのはなぜですか?これを回避するにはどうすればよいですか?

Go の「range」関数がメモリ アドレスを再利用するのはなぜですか?これを回避するにはどうすればよいですか?

Patricia Arquette
リリース: 2024-12-31 01:48:13
オリジナル
758 人が閲覧しました

Why Does Go's `range` Function Reuse Memory Addresses, and How Can This Be Avoided?

Go でのメモリ アドレスの再利用: Range 関数を理解する

Go でスライスを操作する場合、range 関数がどのように相互作用するかを理解することが重要ですあなたのデータと一緒に。プロジェクトで最近発生した問題により、スライス内のポインターの動作に関する疑問が生じました。具体的には、なぜ特定のメソッドが間違ったメモリ アドレスを返したのか、また、代替ソリューションはどのようにしてこの問題を解決できたのでしょうか?

元のメソッド ToModelList は、Region オブジェクト (Regions) のスライスをリストに変換することを目的としていました。モデルインターフェイスの。ただし、リージョンへの最初のポインターが出力内で繰り返し複製されました。これを修正するために、メソッドの修正バージョンが導入されました。

しかし、このわずかな修正はどのような違いをもたらしたのでしょうか?鍵となるのはレンジ関数を理解することです。 ToModelList の最初のバージョンでは、 item がループ変数でした。値が変化しても、アドレスは一定のままです。その結果、出力スライス内の複数の要素に同じアドレスが割り当てられました。

改訂版では、ループ構文が変更されました: for idx, := range *coll。今回は、未使用のループ変数のプレースホルダーとして を使用し、インデックス idx を使用して実際の項目にアクセスできるようにしました。 *coll を介してアイテムに間接的にアクセスすることで、繰り返しごとに新しいアドレスが使用されるようになり、メモリ再利用の問題が解決されました。

これをさらに説明するために、次のコードを考えてみましょう:

func main() {
    coll := []int{5, 10, 15}
    for i, v := range coll {
        fmt.Printf("Always the same: %v\n", &v)
        fmt.Println("Increments by 4 bytes each iteration: %v\n", &coll[i])
    }
}
ログイン後にコピー

この例では、最初のループ変数 v は常に同じメモリ アドレスを参照しますが、2 番目のループ変数 &coll[i] は反復ごとに 4 バイトずつ増加します。これは、ループ変数の使用と要素に直接アクセスすることの違いを示しています。

Go でスライスを操作するには、range 関数の内部動作を理解することが不可欠です。提供されている例では、潜在的な落とし穴と、ループ構文が結果にどのような影響を与える可能性があるかを強調しています。

以上がGo の「range」関数がメモリ アドレスを再利用するのはなぜですか?これを回避するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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