スライスとは動的配列であり、Goで配列を扱う際の主要な構造単位です。歴史的に、プログラミング言語は固定配列やより重い構造を提供していました。Goはスライスを実装して、自動的にサイズを管理し、長さを変更できるメモリコレクションの処理のための便利なツールを提供しました。
問題は、メモリの適切な管理、境界ケース(空、nil、満杯のスライス)の処理、スライスの長さと容量の違いを理解することにあります。
解決策は、組み込み関数 len()、cap() を正しく使用し、Goの規約に従ってスライスを操作することです。
コード例:
var a []int // nilスライス、len=0、cap=0 b := make([]int, 0) // 空のスライス、len=0、cap=0 c := make([]int, 3, 5) // len=3、cap=5 c = append(c, 4, 5, 6) // capは自動的に増加します
主な特徴:
var s []int)はメモリを全く割り当てませんが、空のスライス(make([]int, 0))と内部的にだけ異なります。nilスライスにappendすると、スライスの長さと容量はどうなるか?
Nilスライス(var s []int)はappend(s, 1)の後に長さ1、容量1のスライスになります—Goがストレージを自動的に割り当てます。
var s []int s = append(s, 42) // sは[42]、len=1、cap=1
nilスライスのcapacityにアクセスできますか?
はい、nilスライスの両関数—lenおよびcap—は0を返します。パニックはありません。
var s []int fmt.Println(len(s), cap(s)) // 0 0
nilスライスのインデックスに要素を割り当てようとするとどうなりますか?
「index out of range」のパニックが発生します。スライスには要素がないためです。
var s []int s[0] = 1 // panic: runtime error: index out of range
チームはGoサーバーで常にvar s []Tを使用することに決定し、これが常にmake([]T, 0)と同等であると期待しました。その結果、いくつかのjsonマーシャルがnullを返し、[]ではありませんでした。
利点:
欠点:
make([]T, 0, 100)を使用して事前割り当てを行い、以降はループ内でappendのみを使用する。これにより、メモリのアロケーションが最小化され、パフォーマンスが向上することがあります。
利点:
欠点: