0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Goのスライスを理解する2(append / make / len / cap)

0
Posted at

スライスの理解で一番大事なのが

  • append すると何が起きるのか?
  • lencap の違いは?
  • スライス式(a[i:j])で cap が変わるのはなぜ?

という部分です。

この記事では、サンプルコードを動かしながら

append / make / len / cap と、capの考え方を整理します。

1. はじめに

この記事でわかること:

  • append の基本
  • make([]T, len, cap) の意味
  • lencap の違い
  • スライス式と cap の関係(ここが落とし穴)

2. appendの基本

a := []int{100,200}
a =append(a,300)
fmt.Println(a)// [100 200 300]

ポイント

  • append戻り値を受け取る必要がある
  • append(a, ...)新しいスライスを返す(同じ配列を使う場合もあるし、再確保される場合もある)

3. make と len / cap の確認

スライスは make で作るのが定番です。

l :=make([]int,0,5)
fmt.Println(l)// []
fmt.Printf("len=%d cap=%d value=%v\n",len(l),cap(l), l)// len=0 cap=5 value=[]

make の意味

make([]int,len,cap)
  • len:今使える要素数(実体として存在する長さ)
  • cap:内部配列として確保している容量(appendで増える余地)

4. appendでlenが増える(capの範囲内)

l :=make([]int,0,5)

l =append(l,0,0)
fmt.Printf("len=%d cap=%d value=%v\n",len(l),cap(l), l)// len=2 cap=5 value=[0 0]
  • len は 2 に増える
  • cap は 5 のまま(まだ余裕がある)

5. capを超えたらどうなる?

l =append(l,1,2,3,4,5)
fmt.Printf("len=%d cap=%d value=%v\n",len(l),cap(l), l)
  • len は増える
  • cap は 足りなくなったら増える

⚠️ capの増え方(例:5→10など)は保証されません

環境やGoバージョンによって異なる可能性があります。

6. make([]int, 3) の場合

capを指定しない場合は、len==cap になります。

e :=make([]int,3)
fmt.Printf("len=%d cap=%d value=%v\n",len(e),cap(e), e)// len=3 cap=3 value=[0 0 0]

7. スライス式とcapの関係

スライス式 a[i:j] で作ったスライスは、元の配列を参照します。

そして capは「開始位置から元配列末尾まで」 になります。

7-1. 末尾寄りのスライス(capが小さい)

test := []int{1,2,3,4,5,6}
test2 := test[4:]
fmt.Println(test2)// [5 6]
fmt.Printf("len=%d, cap=%d\n",len(test2),cap(test2))// len=2 cap=2

理由:

  • 開始位置が index=4

  • 元配列の末尾(index=5)までしか残っていない

    → cap が 2 になる

7-2. 先頭寄りのスライス(capが大きい)

test3 := []int{1,2,3,4,5,6}
test4 := test3[:2]
fmt.Println(test4)// [1 2]
fmt.Printf("len=%d, cap=%d\n",len(test4),cap(test4))// len=2 cap=6

理由:

  • 開始位置が index=0

  • 元配列の末尾まで全部が「容量として残っている」

    → cap が 6 になる

7-3. 中間のスライス(lenとcapがずれる)

test5 := []int{1,2,3,4,5,6}
test6 := test5[3:4]
fmt.Println(test6)// [4]
fmt.Printf("len=%d, cap=%d\n",len(test6),cap(test6))// len=1 cap=3

理由:

  • len は 4 - 3 = 1

  • cap は「開始位置 3 から末尾まで」

    → index=3,4,5 の3つ分なので cap=3

8. まとめ

  • append は戻り値を受け取る
  • len は「今の要素数」、cap は「確保している容量」
  • make([]T, len)len==cap
  • cap を超えると内部配列が再確保される(増え方は保証されない)
  • スライス式 a[i:j] の cap は i(開始位置)から末尾まで になる
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?