ホームページ バックエンド開発 Golang Go スライス: 「range」を使用してスライス要素をコピーすると、共有メモリ アドレスが発生する場合があるのはなぜですか?

Go スライス: 「range」を使用してスライス要素をコピーすると、共有メモリ アドレスが発生する場合があるのはなぜですか?

Dec 19, 2024 am 02:12 AM

Go Slices: Why Does Copying Slice Elements Using `range` Sometimes Lead to Shared Memory Addresses?

Go: スライスからコピーしたメモリ アドレスの再利用

Go では、range 関数はスライスの要素を反復処理します。ただし、よくある落とし穴は、ループ変数のメモリ アドレスの再利用です。これにより、スライス要素を別のデータ構造にコピーしようとすると、予期しない結果が生じる可能性があります。

次のコード スニペットを考えてみましょう。

// Regions is the collection of the Region model
type Regions []Region

// Returns the model collection as a list of models
func (coll *Regions) ToModelList() []Model {
    output := make([]Model, len(*coll))
    for idx, item := range *coll {
        output[idx] = &item
    }
    return output
}
ログイン後にコピー

このコードでは、ループ変数項目はポインタ参照です。 *coll スライス内の要素に追加します。 &item を出力スライスの要素に割り当てることにより、複数の要素が同じ基礎となる領域オブジェクトを指すことになります。これは、output と *coll が item の同じメモリ アドレスを共有しているために発生します。

この問題を解決するには、出力内の要素ごとに、Region オブジェクトの個別のコピーを作成する必要があります。これは、次のコード スニペットを使用して実現できます。

// Returns the model collection as a list of models
func (coll *Regions) ToModelList() []Model {
    output := make([]Model, len(*coll))
    for idx, _ := range *coll {
        i := (*coll)[idx]
        output[idx] = &i
    }
    return output
}
ログイン後にコピー

この改訂されたコードでは、_ は *coll にわたる範囲のループ変数として使用されます。これにより、反復ごとに i の新しいコピーが確実に作成され、ループ反復間でのメモリ アドレスの再利用が防止されます。

このような種類の落とし穴を回避し、プログラムを正しく実行するには、Go のメモリ管理の微妙な違いを理解することが重要です。 .

以上がGo スライス: 「range」を使用してスライス要素をコピーすると、共有メモリ アドレスが発生する場合があるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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

ホットな記事タグ

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Go Language Packのインポート:アンダースコアとアンダースコアなしの違いは何ですか? Go Language Packのインポート:アンダースコアとアンダースコアなしの違いは何ですか? Mar 03, 2025 pm 05:17 PM

Go Language Packのインポート:アンダースコアとアンダースコアなしの違いは何ですか?

GOでテスト用のモックオブジェクトとスタブを書くにはどうすればよいですか? GOでテスト用のモックオブジェクトとスタブを書くにはどうすればよいですか? Mar 10, 2025 pm 05:38 PM

GOでテスト用のモックオブジェクトとスタブを書くにはどうすればよいですか?

Beegoフレームワークのページ間で短期情報転送を実装する方法は? Beegoフレームワークのページ間で短期情報転送を実装する方法は? Mar 03, 2025 pm 05:22 PM

Beegoフレームワークのページ間で短期情報転送を実装する方法は?

GOのジェネリックのカスタムタイプ制約を定義するにはどうすればよいですか? GOのジェネリックのカスタムタイプ制約を定義するにはどうすればよいですか? Mar 10, 2025 pm 03:20 PM

GOのジェネリックのカスタムタイプ制約を定義するにはどうすればよいですか?

トレースツールを使用して、GOアプリケーションの実行フローを理解するにはどうすればよいですか? トレースツールを使用して、GOアプリケーションの実行フローを理解するにはどうすればよいですか? Mar 10, 2025 pm 05:36 PM

トレースツールを使用して、GOアプリケーションの実行フローを理解するにはどうすればよいですか?

Linterと静的分析ツールを使用して、GOコードの品質と保守性を向上させるにはどうすればよいですか? Linterと静的分析ツールを使用して、GOコードの品質と保守性を向上させるにはどうすればよいですか? Mar 10, 2025 pm 05:38 PM

Linterと静的分析ツールを使用して、GOコードの品質と保守性を向上させるにはどうすればよいですか?

Go言語でファイルを便利に書く方法は? Go言語でファイルを便利に書く方法は? Mar 03, 2025 pm 05:15 PM

Go言語でファイルを便利に書く方法は?

MySQLクエリ結果リストをGO言語のカスタム構造スライスに変換する方法は? MySQLクエリ結果リストをGO言語のカスタム構造スライスに変換する方法は? Mar 03, 2025 pm 05:18 PM

MySQLクエリ結果リストをGO言語のカスタム構造スライスに変換する方法は?

See all articles