ホームページ > バックエンド開発 > Golang > Go スライスのコピーを変更するとオリジナルも変更されるのはなぜですか?

Go スライスのコピーを変更するとオリジナルも変更されるのはなぜですか?

Barbara Streisand
リリース: 2024-11-19 06:44:02
オリジナル
266 人が閲覧しました

Why Does Modifying a Go Slice Copy Also Change the Original?

Go でのスライスの変更を理解する

Go では、スライス変数は通常の配列とは異なる動作をします。これにより、特にスライスを変更する場合に、予期しない動作が発生する可能性があります。

元のスライスの変化の謎

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

import "fmt"

func main() {
    A := []int{3, 4, 5, 3, 7}

    fmt.Println("Initial slice: ", A)
    funcSome(A)
    fmt.Println("Modified slice: ", A)
}

func funcSome(slice []int) {
    fmt.Println("Inside function, original slice: ", slice)
    temp := slice // copy by value

    temp[0] = 10
    fmt.Println("Inside function, modified temp: ", temp)
    fmt.Println("Inside function, original slice: ", slice)
}
ログイン後にコピー

このコードを実行すると、一時スライス temp を変更すると元のスライスも変更されることに驚くかもしれません。 A.

スライスの内部構造の詳細

この動作を理解するには、スライスの内部構造を詳しく理解する必要があります。スライス変数は 3 つのコンポーネントで構成されます。

  • ポインタ: データを保持するバッキング配列を指します
  • 長さ: スライス内の要素の数
  • 容量:スライスの最大容量

一時の場合のように、スライスを新しい変数に値で代入する場合:= スライス、浅いコピー を作成しています。これは、新しいスライス (temp) が元のスライス (スライス) と同じバッキング配列とポインターを共有することを意味します。

append() のジレンマ

The append( Go の) 関数は、新しいバッキング配列を作成し、そこに既存のデータをコピーすることで、要素をスライスに追加します。ただし、新しいスライスの容量が不十分な場合、append() 関数はより大きなバッキング配列を再割り当てすることで自動的に容量を増やします。

この例では、remove() 関数は append() を使用して新しいスライスを作成します。スライス。 temp と A は同じバッキング配列を共有しているため、新しいスライスへの変更は元のスライスにも影響します。

結論

Go でのスライスの変更を理解するには、次の知識が必要です。そのユニークな内部構造。スライスを値でコピーするときは、同じバッキング配列を共有する浅いコピーを作成することになることに注意してください。この動作により、スライスを変更するときに予期しない結果が生じる可能性があります。

以上がGo スライスのコピーを変更するとオリジナルも変更されるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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