ホームページ  >  記事  >  バックエンド開発  >  Go の「append()」関数は常に新しいスライスを作成しますか?

Go の「append()」関数は常に新しいスライスを作成しますか?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-10-31 03:17:30724ブラウズ

Does Go's `append()` Function Always Create a New Slice?

Go で append() を使用すると新しいスライスが作成されるのはいつですか?

コンテキスト:

Go の append() 関数は、1 つ以上の要素をスライスに追加するために使用され、元のスライスの容量が不十分な場合に新しいスライスを作成することが文書化されています。しかし、スライスに要素を追加する再帰的アルゴリズムの調査により、チャネル経由で送信されたスライスは送信後に変更されるようであることが判明しました。

混乱:

この観察は、append() が新しいスライスを返す必要があることを示すドキュメントと矛盾します。この混乱は、append() のドキュメントではスライスのデータ型を参照しているのに、実際の実装ではスライス記述子を使用するために発生します。

解決策:

スライス記述子は次のもので構成されます。 3 つのコンポーネント: 長さ、容量、および基礎となるデータへのポインター。 append() が呼び出されると、長さと容量が更新された新しいスライス記述子が返されます。ただし、基になるデータへのポインタは変わりません。

説明:

したがって、append() は新しいスライス記述子を返しますが、実際のデータはそのままです。古いスライスと新しいスライスの間で共有されます。これは、基礎となるデータがスライス記述子によって指定される別のメモリ位置に格納されるためです。

例:

次のコードは、この動作を示しています。

<code class="go">package main

import "fmt"

func main() {
    s := make([]int, 0, 5)
    s = append(s, []int{1, 2, 3, 4}...)

    a := append(s, 5)
    fmt.Println(a)

    b := append(s, 6)
    fmt.Println(b)
    fmt.Println(a)
}</code>

出力は、変更された 2 つのスライス a と b が、長さと容量が異なるにもかかわらず、元のスライス s と同じ基礎となるデータを共有していることを示しています。

以上がGo の「append()」関数は常に新しいスライスを作成しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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