Go言語におけるスライスの len
と cap
の違いについて説明します。
len
と cap
の違い
-
len
: スライスの現在の要素数を返します。これは、スライスに格納されている実際のデータの数を示します。 -
cap
: スライスが持つことのできる最大の要素数を返します。これは、スライスが内部的に保持している配列の容量を示します。
スライスの動作
スライスは、配列のラッパーとして機能し、動的にサイズを変更できます。スライスの容量は、要素を追加する際に増加することがあります。具体的には、スライスの容量は以下のように変化します。
package main
import "fmt"
func main() {
var x []int
fmt.Println(x, len(x), cap(x)) // [] 0 0
x = append(x, 10)
fmt.Println(x, len(x), cap(x)) // [10] 1 1
x = append(x, 20)
fmt.Println(x, len(x), cap(x)) // [10 20] 2 2
x = append(x, 30)
fmt.Println(x, len(x), cap(x)) // [10 20 30] 3 4
x = append(x, 40)
fmt.Println(x, len(x), cap(x)) // [10 20 30 40] 4 4
x = append(x, 50)
fmt.Println(x, len(x), cap(x)) // [10 20 30 40 50] 5 8
}
-
初期状態: スライスが初期化されると、
len
とcap
は両方とも0
です。x := []int{} // len(x) = 0, cap(x) = 0
-
最初の要素の追加:
append
を使って要素を追加すると、長さと容量が両方とも1
になります。x = append(x, 10) // len(x) = 1, cap(x) = 1
-
2つ目の要素の追加: 再度
append
を使うと、長さは2
になりますが、容量も2
となります。これは、スライスの内部配列が新しい要素を格納するために十分な容量を持っているためです。x = append(x, 20) // len(x) = 2, cap(x) = 2
-
3つ目の要素の追加: 3つ目の要素を追加すると、既存の容量を超えるため、新しい配列が作成され、容量が
4
になります。x = append(x, 30) // len(x) = 3, cap(x) = 4
-
4つ目の要素の追加: 容量が十分なため、長さは
4
で、容量は4
のままです。x = append(x, 40) // len(x) = 4, cap(x) = 4
-
5つ目の要素の追加: またもや容量を超えるため、内部配列が再割り当てされ、容量が
8
に増加します。x = append(x, 50) // len(x) = 5, cap(x) = 8
まとめ
- スライスの
len
は現在の要素数、cap
はスライスが保持できる最大の要素数を示します。 -
append
操作を行う際に、現在の容量を超えると新しい配列が作成され、容量が増加します。この動的な管理により、Go言語のスライスは効率的にメモリを使用します。