🥣

::: Goのsliceまとめ :::

2022/09/10に公開約1,600字

sliceとは

sliceは配列型の上に構築された抽象概念。
Goではarrayよりsliceを使うことが多い。
sliceは長さの指定をしない。

letters := []string{"a", "b", "c", "d"}

sliceのゼロ値はnil。len(s)は0、cap(s)も0を返す。

makeという組み込み関数を用いて作成することもできる。

func make([]T, len, cap) []T

capが省略された場合、lengthと同じ値(以下であれば5)になる。

s := make([]byte, 5)

sliceの内部

sliceはarray segmentを表す記述子。arrayへのポインタ、length(スライスが参照する要素数)、capacity(スライスポインタによって参照される要素から始まる基礎となる配列の要素数)の3つで構成されている。

先述のs変数は以下のように構築される。

画像出典:Go Slices: usage and internals

s変数をスライスすると、sliceのデータ構造と基底配列との関係性が変わる。

s = s[2:4]


画像出典:Go Slices: usage and internals

スライスすると、同じarrayにポインタが向いた新しいsliceが作成される。
そのため、新しく作成されたsliceの要素を変更すると、元のsliceの要素も変更される。

d := []byte{'r', 'o', 'a', 'd'}
e := d[2:]
// e == []byte{'a', 'd'}
e[1] = 'm'
// e == []byte{'a', 'm'}
// d == []byte{'r', 'o', 'a', 'm'}

capacityよりlengthが短い場合、capacityの大きさまでは再度スライスできる。

s = s[:cap(s)]


画像出典:Go Slices: usage and internals

Sliceは、capacityを超えて拡張はできない。
また、0以下に再スライスして元の配列にアクセスすることはできない。

sliceの容量を増やす

sliceのcapacityを増やすには、元のsliceよりも容量が大きな新しいsliceを作り、そこに元のsliceの内容をコピーする必要がある。

WIP...

参照

https://go.dev/blog/slices-intro
https://qiita.com/imoty/items/bb18fb50d526474d2d10
https://gosamples.dev/capacity-and-length/

Discussion

ログインするとコメントできます