LoginSignup
73
53

More than 5 years have passed since last update.

Goのarrayとsliceとmapを理解する #golang

Last updated at Posted at 2017-07-26

array

長さがポイント

  • 固定長配列
  • 初期値は0

書き方
[長さ]型{値}

    var a1 [5]int            // array型の変数を宣言するとき(初期値0が入る)
    var a2 = [5]int{1, 2, 3} // 配列を作って初期値を指定するとき
    a3 := [5]int{1, 2, 3}    // 代入演算子を使って簡易表記するとき
    a4 := [...]int{1, 2, 3}  // 長さを省略するとき

    fmt.Println(a1, len(a1)) // [0 0 0 0 0] 5
    fmt.Println(a2, len(a2)) // [1 2 3 0 0] 5
    fmt.Println(a3, len(a3)) // [1 2 3 0 0] 5
    fmt.Println(a4, len(a4)) // [1 2 3] 3



    a1[2] = 5 // 値を変更するとき
    fmt.Println(a1) // [0 0 5 0 0]

slice

ポインタと容量がポイント

  • 可変長配列のようなもの
  • 初期値はnil

arrayと比較して以下の違いがある。

  • 実体(array)とポインタの両方を持っている
    • ポインタ: エイリアスのようなもので、アドレスとも呼ばれる
  • 容量(cap)を持っている
    • 長さ < 容量 < 参照元の容量 の範囲内で指定できる
    • スライスをスライスするときは[]の三番目に指定できる

書き方
[]型{値}

    var s1 []int               // slice型の変数を宣言するとき(初期値nilが入る)
    var s2 = []int{1, 2, 3, 4} // 値を指定するとき
    s3 := []int{1, 2, 3, 4}    // 代入演算子を使って簡易表記するとき

    fmt.Println(s1, len(s1), cap(s1)) // [] 0 0
    fmt.Println(s2, len(s2), cap(s2)) // [1 2 3 4] 4 4
    fmt.Println(s3, len(s3), cap(s3)) // [1 2 3 4] 4 4



    s3s := s3[0:2]                       // sliceをsliceするとき
    fmt.Println(s3s, len(s3s), cap(s3s)) // [1 2] 2 4(容量を指定しないと参照元を引き継ぐ)



    s3sc := s3[0:2:3]                       // 容量を指定してsliceをsliceするとき
    fmt.Println(s3sc, len(s3sc), cap(s3sc)) // [1 2] 2 3

:star:組み込み関数make()を使う場合

  • 長さと容量を指定し、sliceをつくる
  • 長さは省略できないが、容量は省略できる
  • 容量を省略すると、要素数=容量となる
  • 初期値は0
  • make関数はスライスを初期化する。初期値としてnilではなく0を格納する

書き方 : make(型, 要素数, 容量)

    var sm1 = make([]int, 5)      // 容量を省略してsliceをつくるとき(初期値0が入る)
    var sm2 = make([]int, 5, 10)  // 容量を指定してsliceをつくるとき
    sm3 := make([]int, 5, 10)     // 代入演算子を使って簡易表記するとき

    fmt.Println(sm1, len(sm1), cap(sm1)) // [0 0 0 0 0] 5 5
    fmt.Println(sm2, len(sm2), cap(sm2)) // [0 0 0 0 0] 5 10
    fmt.Println(sm3, len(sm3), cap(sm3)) // [0 0 0 0 0] 5 10

:warning: 組み込み関数make()は参照型にしか使えない。(slice, map, channel)

map

キーがポイント

  • 連想配列のようなもの(辞書・ハッシュetc.)
  • 初期値は nil

arrayやsliceと比較して以下の違いがある。

  • 実体(array)を持っていない
  • 組み込み関数cap()は使えない

書き方
map[キー]型

    var m1 map[int]string    // map型の変数を宣言するとき(初期値0が入る)

    var m2 = map[string]int{ // 値を指定するとき
        "dora": 0,
        "nobi": 1,
    }

    m3 := map[string]int{    // 代入演算子を使って簡易表記するとき
        "shizu":   0,
        "jai": 1,
        "sune":   2,
    }

    fmt.Println(m1, len(m1)) // map[] 0
    fmt.Println(m2, len(m2)) // map[dora:0 nobi:1] 2
    fmt.Println(m3, len(m3)) // map[shizu:0 jai:1 sune:2] 3




    m3["deki"] = 3 // 要素を追加するとき
    // m3[1:"dora"]
    fmt.Println(m3, len(m3)) // map[shizu:0 jai:1 sune:2 deki:3] 4

    m3["shizu"] = 100        // キーをもとに値を書き換えるとき
    fmt.Println(m3, len(m3)) // map[shizu:100 jai:1 sune:2 deki:3] 4

:star:組み込み関数make()を使う場合

  • 容量を指定し、mapをつくる
  • 容量は省略できる
  • 初期値は0

書き方
make(map[キーの型]要素型, 容量)

    var mm1 = make(map[int]int)       // 容量を省略してmapをつくるとき(初期値0が入る)
    var mm2 = make(map[int]string, 5) // 容量を指定してmapをつくるとき
    mm3 := make(map[int]int, 5)       // 代入演算子を使って簡易表記するとき

    fmt.Println(mm1, len(mm1)) // map[] 0
    fmt.Println(mm2, len(mm2)) // map[] 0
    fmt.Println(mm3, len(mm3)) // map[] 0



    var mm4 = make(map[string]string, 4) // 値を指定するとき(makeを使う場合、代入する形になる)
    mm4["鳥"] = "bird"
    mm4["木"] = "tree"

    fmt.Println(mm4, len(mm4)) // map[鳥:bird 木:tree] 2

参考:
Go言語: いろいろなマップの作り方まとめ-Qiita

Tips

  • Goでは初期値を「ゼロ値」と呼ぶ
  • 「型」と「リテラル」は別物
ex) var a int = 0x0719BEEFの場合

型: int
リテラル: 10x0719BEEF(値)を指す場合とvar a int = 0x0719BEEF(表記そのもの)を指す場合がある

組み込み関数make()とnew()の違い

  • make()は実体(array)をつくる。実体を返す。もともと実体を持っていない参照型にのみ使える。
  • new()はメモリを割り当てるだけで、実体はつくらない。ポインタを返す。一般的に構造体型のメモリ割り当てにおいて使われる
73
53
1

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
73
53