LoginSignup
1
0

More than 3 years have passed since last update.

Golangの配列とスライスを整理する

Last updated at Posted at 2020-02-03

全くもって真新しい情報はないが、自分の勉強がてらのアウトプット。

最初に

  • 配列はunderying arrayを参照している
  • The programmers should avoid exposing the array and always keep it anonymousらしい(参考)

配列

  • 配列は長さ(capacity)を持つ(初期化時に固定される)
  • ゆえに要素の追加はできない

  • 配列の初期化

# 配列の初期化
a := [...]int{5, 10, 15,}
a := [3]int{5, 10, 15,}

スライス

  • スライスは配列を参照している

  • スライスは長さ(length)と容量(capacity)の両方を持っている。

    • スライス内の要素を書き換えると、元のundelying arrayを書き換える事になる
    • スライスに新しい要素をappendすると、元のundelying arrayを書き換え、またlenとcapの両方が拡張される
  • スライスはlenが可変長。可変長と言えどcapが限界。

The maximal capacity of the slice = 
the capacity of the underlying array - 
the position of the start of the slice in the array :


 array : [0 0 0 0 0 0 0 0 0 0 0 0]
 array :  <----   capacity   --->
 slice :     [0 0 0 0]
 slice :      <---- capacity ---> 

以上参考

  • スライスの初期化
# (1)スライスの定義(len=cap=2になる)
s := []int{}
s := []int{5, 10,}

# (2)配列からスライスを定義
a := [100]int
s := a[1:4]
# スライスからスライスを定義(capの範囲ならlenをブチ抜けていい)
s2 := s[1:50]

# (3)スライスを定義する際にunderlying arrayも同時に定義(各要素の初期値はintだとゼロ)
## できるスライスのcap=len=4
slice1 := make([]int, 4)
## できるスライスのlen=2,cap=4 
slice2 := make([]int, 2, 4)

参考によると、(1)の定義方法だと、容量 (cap) はいっぱいになるたびに2倍、2倍と拡張されている(筆者メモ:JavaのArrayListと同じ仕組み)。 容量の拡張時には、内部で新しいメモリ領域へのデータコピーが発生するため、頻繁な容量拡張が発生すると効率が悪い。 あらかじめ追加するおおよその要素数が分かっている場合は、(3)のmake 関数を使うことで、容量を指定したスライス生成を行える。

  • 要素の追加
# 新しいスライスを返す
newSlice := append(s, 20)

その他メモ

  • 配列は固定長、リストは可変長

参考

1
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
1
0