ホームページ >バックエンド開発 >Golang >ループから新しいスライスを作成するとスライス追加の動作が変わるのはなぜですか?

ループから新しいスライスを作成するとスライス追加の動作が変わるのはなぜですか?

DDD
DDDオリジナル
2024-11-03 12:46:31563ブラウズ

Why Does Slice Append Behavior Change When Creating New Slices from a Loop?

予期しないスライス追加動作

問題の概要

ループを実行した後、ループ結果から新しいスライスを作成しようとすると、予期しない動作が発生します。具体的には、最後の追加要素は、前の追加の結果を上書きします。この問題は、ループ反復から取得したスライスに基づいて新しいスライスを作成するときに発生します。

分析

観察された動作は、Go スライスと配列の両方が使用するという事実に起因しています。同じ基礎となるデータ構造。スライスに追加するとき、Go は同じ基礎となる配列を参照する新しいスライス オブジェクトを作成します。これは、元のスライスに加えられた変更は新しいスライスにも影響することを意味します。

解決策

この動作を回避するには、スライスを作成する前にスライスをコピーすることが重要です。あらゆる変更。これにより、基になる配列への独自の独立した参照を持つ新しいスライス オブジェクトが作成されます。これを実現する慣用的な方法は、copy 関数を使用することです。

<code class="go">func makeFromSlice(sl []int) []int {
    result := make([]int, len(sl))
    copy(result, sl)
    return result
}</code>

makeFromSlice(i) の結果を main 関数の j に代入することで、元の i から独立した新しいスライスを作成します。スライス。この新しいスライスは、元のスライスに影響を与えることなく安全に変更できます。

スライス リテラルとの対比

スライス リテラル ({0、1、2、3、4、など) 5, 6, 7, 8, 9, 10}、容量を超えて追加された場合は、常に新しい基になる配列を割り当てます。これは、sliceFromLiteral が期待どおりに動作する理由を説明しています。

結論

スライスを操作するときは、変更する前に必ずコピーを作成してください。これにより、新しいスライスに加えられた変更が元のスライスに影響を与えなくなります。 copy 関数は、これを行うための慣用的かつ効率的な方法を提供します。

以上がループから新しいスライスを作成するとスライス追加の動作が変わるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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