目次
質問内容
解決策
ホームページ バックエンド開発 Golang Go で `append(x, x...)` がスライスを新しいバッキング配列にコピーするのはなぜですか?

Go で `append(x, x...)` がスライスを新しいバッキング配列にコピーするのはなぜですか?

Feb 10, 2024 am 11:12 AM

为什么 `append(x, x...)` 将切片复制到 Go 中的新支持数组中?

php エディターの Youzi が、誰にとってもよくある質問に答えます。「append(x, x...)」はなぜ Go の新しいサポート配列にスライスをコピーするのですか? Go プログラミング言語では、要素をスライスに追加するために「append」関数が使用されます。 「append」関数を使用するとき、スライスの容量が不十分な場合、Go は新しい基になる配列を作成し、元のスライスの要素を新しい基になる配列にコピーします。これは、Go ではスライスは動的配列への参照であるため、スライスの容量が十分でない場合は、より多くの要素を収容するために新しい配列を作成する必要があります。このメカニズムにより、スライスの連続性とスケーラビリティが保証されますが、パフォーマンスの低下も引き起こします。

質問内容

go のスライス ヒント wiki や go ライブラリ (この例など) では、スライスを新しいバッキング配列の中央にコピーするための次のようなコードが表示されることがあります。

リーリー

私が理解していると思うことは次のとおりです:

  • append の 2 番目の引数としてスライス内のすべての項目が新しいバッキング配列にコピーされます。
  • append の最初のパラメータでは、コードは完全なスライス式を使用します。 (最初のパラメータを a[0:0:0] に書き換えることもできますが、省略した場合は、最初の 0 が提供されます。これは、ここでのより一貫性があると思います。意味は関係ありません。)
  • 仕様によれば、生成されるスライスは元のスライスと同じタイプであり、長さと容量はゼロである必要があります。
  • (これも直接関係ありませんが、append の代わりに copy を使用すると、よりわかりやすくなります。)

ただし、構文 append(someslice[:0:0], someslice...) が新しいバッキング配列を作成する理由がまだよくわかりません。私も最初は、なぜ append 操作で元のスライスが台無しにされない (または切り捨てられない) のかについて混乱しました。

今の私の推測:

  • newslice := oldslice を割り当てるだけで、一方への変更がもう一方にも反映されるため、これらはすべて必要かつ有用であると思います。通常、これは望ましくありません。
  • append の結果を元のスライスに代入していないため (これは Go では正常です)、元のスライスには何も起こりません。切り捨てられたり、変更されたりすることはありません。
  • anyslice[:0:0] の長さと容量はゼロなので、Go が anyslice の要素を結果に割り当てたい場合は、新しいサポートを作成する必要があります配列。これは新しいバッキング配列を作成する 理由ですか?
  • anyslice... に要素がない場合はどうなりますか? Go プレイグラウンドのスニペットは、空のスライスでこの追加のトリックを使用すると、コピーとオリジナルが最初は同じバッキング配列を持つことを示しています。 (編集: コメント投稿者が説明したように、私はスニペットを誤解しました。スニペットは、両方の項目が最初は同じであることを示していますが、どちらも配列をサポートしていません。両方ともオリジナルがユニバーサルであることを示しています両方のスライスの長さと容量がゼロであるため、いずれかのスライスに何かを追加すると、そのスライスは新しいバッキング配列を取得します。ですので、効果は今も同じだと思います。つまり、append コピー後、2 つのスライスは相互に影響を与えることはできません。
  • この他のプレイグラウンド スニペットは、スライスに 0 個以上の要素がある場合、append copy メソッドが新しいバッキング配列を直ちに生成することを示しています。この場合、結果として得られる 2 つのスライスは、いわばすぐに分離されます。

これについてはおそらく過度に心配していますが、 理由 append(a[:0:0], a...) についてもっと詳しく説明していただきたいです。トリックワークスもそうです。

解決策

anySlice[:0:0] の長さと容量はゼロであるため、Go が anySlice の要素を結果に割り当てたい場合は、新しいバッキング配列を作成する必要があります。これが新しいバッキング配列が作成された理由ですか?

容量は 0 なので、そうです。

https://pkg.go.dev/[email protected]#追加

十分な容量がある場合は、新しい要素を収容するためにターゲットが再スライスされます。そうでない場合は、新しい基になる配列が割り当てられます。

  • cap=0 は空でないスライスには不十分です。新しい配列を割り当てる必要があります。

以上がGo で `append(x, x...)` がスライスを新しいバッキング配列にコピーするのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++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のパッケージインポートメカニズム:名前付きインポート(例:インポート "fmt")および空白のインポート(例:_" fmt")について説明しています。 名前付きインポートはパッケージのコンテンツにアクセス可能になり、空白のインポートはtのみを実行します

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

この記事では、Webアプリケーションでのページ間データ転送のためのBeegoのnewflash()関数について説明します。 newflash()を使用して、コントローラー間で一時的なメッセージ(成功、エラー、警告)を表示し、セッションメカニズムを活用することに焦点を当てています。 リミア

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

この記事では、MySQLクエリの結果をGO structスライスに効率的に変換することを詳しく説明しています。 データベース/SQLのスキャン方法を使用して、手動で解析することを避けて強調しています。 DBタグとロブを使用した構造フィールドマッピングのベストプラクティス

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

この記事では、ユニットテストのためにGOのモックとスタブを作成することを示しています。 インターフェイスの使用を強調し、模擬実装の例を提供し、模擬フォーカスを維持し、アサーションライブラリを使用するなどのベストプラクティスについて説明します。 articl

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

この記事では、GENICSのGOのカスタムタイプの制約について説明します。 インターフェイスがジェネリック関数の最小タイプ要件をどのように定義するかを詳しく説明し、タイプの安全性とコードの再利用性を改善します。 この記事では、制限とベストプラクティスについても説明しています

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

この記事では、goで効率的なファイルの書き込みを詳しく説明し、os.writefile(小さなファイルに適している)とos.openfileおよびbuffered write(大規模ファイルに最適)と比較します。 延期エラー処理、Deferを使用し、特定のエラーをチェックすることを強調します。

Goでユニットテストをどのように書きますか? Goでユニットテストをどのように書きますか? Mar 21, 2025 pm 06:34 PM

この記事では、GOでユニットテストを書くことで、ベストプラクティス、モッキングテクニック、効率的なテスト管理のためのツールについて説明します。

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

この記事では、トレースツールを使用してGOアプリケーションの実行フローを分析します。 手動および自動計装技術について説明し、Jaeger、Zipkin、Opentelemetryなどのツールを比較し、効果的なデータの視覚化を強調しています

See all articles