はじめに
前回の続きで Go 言語の文法をまとめておきたいと思います。
- Go言語基礎 その1 Go言語入門
- Go言語基礎 その2 Go言語の開発環境と go コマンド
- Go言語基礎 その3 Go言語の基本構文1 (コメント, 型, 変数, 定数, 演算子)
- Go言語基礎 その4 Go言語の基本構文2 (関数, init, 制御構文)
- Go言語基礎 その5 Go言語の基本構文3 (配列, interface, slice, map, 型アサーション, Defined type, Type alias)
- Go言語基礎 その6 Go言語の基本構文4 (ポインタ, 構造体, メソッド, タグ, インターフェイス)
- Go言語基礎 その7 Go言語の基本構文5 (可視性, スコープ, goto, defer, panic, recover, goroutine, channel)
Go言語文法
その他の基本型
- 配列型
[]
- interface{} 型
interface{}
すべての型と互換 - nil 型
nil
// 配列型
a1 := [5]int{1, 2, 3, 4, 5}
fmt.Printf("%v", a1) // => [1, 2, 3, 4, 5]
a[1] = 3
a[5] = 6 // runtime error
a[-1] = 3 // runtime error
// ... で 要素数を省略できる
a2 := [...]int{1, 2, 3} // == [3]int{1, 2, 3}
// interface{} 型
var x1 interface{} = 3.14
// interface{} 型
// ゼロ値はnil
var x2 interface{} // nil
slice(スライス)
// sliceのゼロ値はnil
var s1 []int // == nil
// makeで生成
s2 := make([]int, 5, 30) // 要素数5, 容量30 の int型のスライスを生成
// len, capで要素数、容量を取得できる
len(s2) // == 5
cap(s2) // == 30
fmt.Println(s2) // => [0, 0, 0, 0, 0]
// index access
s2[0] = 1
s2[1] = 2
fmt.Println(s2) // => [1, 2, 0, 0, 0]
// 簡易スライス式
s3 := s2[0:2] // s3 == [1, 2]
s4 := s2[:3] // s3 == [1, 2, 0]
s5 := s2[2:] // s3 == [0, 0, 0]
s6 := s2[:] // s3 == [1, 2, 0, 0, 0]
// 文字列の簡易スライス式
// []byteであるとみなした上で処理
s7 := "あいうえお"[3:9] // s == "いう"
// append で slice の末尾に追加
s2 = append(s2, 3) // s2 == [1, 2, 0, 0, 0, 3]
s2 = append(s2, s3...) // s2 == [1, 2, 0, 0, 0, 3, 1, 2]
// copy
// コピー先の要素分だけコピーが実行される
i1 := []int{1, 2, 3, 4, 5}
i2 := []int{11, 12}
copy(i2, i1) // i2 == [1, 2]
// 可変長引数とスライス
func output(args ...string) {
for _, s := range args {
fmt.Println(s)
}
}
output("Apple", "Banana", "Cherry")
s8 := ["Apple", "Banana", "Cherry"]
// 配列を展開して渡す場合 ... をつける
output(s8...)
配列は値渡し、スライスは参照渡しで別物
スライスはもとの配列を共有することがあるので注意
a1 := []int{1, 2, 3, 4, 5}
a2 := a1[0:2] // a2 == [1, 2]
// a2の値も変更されている
a1[1] = 0 // a2 == [1, 0]
map(マップ)
// 宣言
var m map[int]string
// 要素の代入
m[1] = "Hoge"
m[2] = "Fuga"
m[1] = "Piyo" // キーが重複すると上書きされる
fmt.Println(m) // => map[1:Piyo 2:Fuga]
// 要素の参照
i := m[7] // i == 0
s, ok := m[1] // s == "Hoge", ok == true
s, ok := m[4] // s == "", ok == false
len(m) // == 3
delete(m, 2)
delete(m, 3) // 何も行われない
fmt.Println(m) // => map[1:Piyo]
キーと要素のペアをまとめて生成する書き方
m := map[int]string{
1: "Hoge",
2: "Fuga",
3: "Piyo",
}
省略記法
m := map[int]map[float64]string{
1: {3.14: "円周率"}
}
範囲節による for はキーの順序は保証されない
m := map[int]string{
1: "Hoge",
2: "Fuga",
3: "Piyo",
}
for _, str := range m {
// Hoge -> Fuga -> Piyoの順で表示されるとは限らない
// 順序不定
fmt.Println(str)
}
型アサーション
- インターフェースの値が特定の型を保持しているかどうかををチェックできます。
- 保持していれば、値と true を返します。保持していない場合、ゼロ値と false が返されます。
value, ok := x.(type)
のように 2 つめの戻り値をok
にする慣例があります
var x interface{} = 3.14
i, ok := x.(int) // i == 0, ok == false
Defined type と Type alias
// 別名として定義 (Defined type)
// 完全に違う型として扱われる
type MyInt int
// 型エイリアス (Type alias)
// 異なる名前で同じ型
type MyFloat = float
参考にした本
おわりに
次回は Go 言語の文法の続きを復習したいと思います。