GolangにおけるSliceの渡し方とAppendの理解
Daniel Hayes
Full-Stack Engineer · Leapcell

Goでは、スライスは配列への動的なインターフェースを提供する強力かつ柔軟なデータ構造です。スライスを関数に渡し、append
関数を効果的に使用する方法を理解することは、効率的なGoプログラミングに不可欠です。
Key Takeaways
- スライスを関数に渡すと、スライスヘッダーがコピーされますが、両方とも同じ基になる配列を指します。
- 関数内でスライスを変更すると、
append
が新しい割り当てをトリガーしない限り、元のスライスに影響します。 append
関数は、既存の容量を超えた場合、新しい配列を割り当てる可能性があります。
関数へのスライスの渡し方
Goでスライスを関数に渡す場合、基になる配列ではなく、スライスヘッダーのコピーを渡しています。これは、関数がスライスヘッダーの自身のコピー(基になる配列へのポインタ、長さ、容量を含む)を受け取る一方で、元のスライスと関数のコピーの両方が同じ基になる配列を指すことを意味します。したがって、関数内のスライスの要素に対する変更は、元のスライスに影響します。
ただし、新しい要素を追加するなど、関数内でスライス自体を変更する場合、既存の配列に十分な容量がない場合、関数のスライスヘッダーのコピーは新しい基になる配列を指すことがあります。この場合、元のスライスは変更されません。元のスライスでそのような変更を反映するには、関数から変更されたスライスを返し、再割り当てするか、スライスへのポインタを渡すことができます。
例:関数内でのスライスの変更
package main import "fmt" func modifySlice(s []int) { s[0] = 10 // 最初の要素を変更; 元のスライスに影響 s = append(s, 20) // 新しい要素を追加; 容量を超えた場合、元のスライスに影響しない可能性あり fmt.Println("関数内:", s) } func main() { nums := []int{1, 2, 3} modifySlice(nums) fmt.Println("関数外:", nums) }
出力:
関数内: [10 2 3 20]
関数外: [10 2 3]
この例では、s[0]
の変更は元のスライスnums
に影響します。ただし、append
操作により、元の配列の容量を超えた場合、s
が新しい基になる配列を指す可能性があり、関数外ではnums
が変更されずに残ります。
append
関数の使用
Goの組み込みappend
関数は、スライスの末尾に要素を追加するために使用されます。スライスに十分な容量がある場合、要素は既存の配列に追加されます。そうでない場合、新しい配列が割り当てられ、要素がそれに追加されます。append
関数は更新されたスライスを返し、新しい基になる配列を指すことがあります。
構文:
newSlice := append(originalSlice, elements...)
例:スライスへの要素の追加
package main import "fmt" func main() { nums := []int{1, 2, 3} nums = append(nums, 4, 5) fmt.Println(nums) // 出力: [1 2 3 4 5] }
あるスライスを別のスライスに追加するには、...
演算子を使用して2番目のスライスの要素を展開します。
package main import "fmt" func main() { slice1 := []int{1, 2, 3} slice2 := []int{4, 5, 6} slice1 = append(slice1, slice2...) fmt.Println(slice1) // 出力: [1 2 3 4 5 6] }
FAQs
要素への直接的な変更は元のスライスに影響を与えますが、append
は新しい配列を割り当て、変更を分離することがあります。
変更されたスライスを返して再割り当てするか、スライスへのポインタを渡します。
Goは新しい配列を割り当て、要素をコピーし、新しい配列を指すようにスライスヘッダーを更新します。
この例では、slice2...
はslice2
の要素を展開し、append
はそれらをslice1
に追加します。
重要なポイント
-
スライスを関数に渡すと、スライスヘッダーがコピーされますが、元のスライスとコピーの両方が同じ基になる配列を指します。
-
関数内のスライスの要素を変更すると、元のスライスに影響します。
-
関数内でスライスに追加すると、
append
が新しい配列を割り当てる可能性があるため、基になる配列の容量を超えた場合、元のスライスに影響を与えないことがあります。 -
関数内でのスライスへの変更が元のスライスに反映されるようにするには、変更されたスライスを返して再割り当てするか、スライスへのポインタを渡します。
これらの動作を理解することは、Goでの効果的なスライス操作に不可欠です。
Goプロジェクトのホスティングに最適なLeapcellはこちらです。
Leapcellは、Webホスティング、非同期タスク、およびRedis向けの次世代サーバーレスプラットフォームです。
多言語サポート
- Node.js、Python、Go、またはRustで開発できます。
無制限のプロジェクトを無料でデプロイ
- 使用量に応じてのみ支払い—リクエストも料金もありません。
比類のないコスト効率
- アイドル料金なしの従量課金制。
- 例:25ドルで平均応答時間60msで694万リクエストをサポートします。
合理化された開発者エクスペリエンス
- 簡単なセットアップのための直感的なUI。
- 完全に自動化されたCI/CDパイプラインとGitOps統合。
- 実用的な洞察を得るためのリアルタイムメトリックとロギング。
簡単なスケーラビリティと高性能
- 高い同時実行性を容易に処理するための自動スケーリング。
- 運用オーバーヘッドはゼロ—構築に集中するだけです。
詳細については、ドキュメントをご覧ください。
Xでフォローしてください:@LeapcellHQ