概要
Go 言語の仕様まとめ。
前回:
Go 言語仕様4(defer, panic, recover)
内容
- スライス
- マップ
スライス
- 基本的なところ
宣言
var sl []int
fmt.Println(sl) // []
var sl2 []int = []int{1, 2, 3}
fmt.Println(sl2) // [1 2 3]
sl3 := []int{10, 20, 30}
fmt.Println(sl3) // [10 20 30]
// make([]型, 要素数, キャパシティ)
sl4 := make([]int, 5, 10)
fmt.Println(sl4) // [0 0 0 0 0]
代入
sl := make([]int, 5, 10)
sl4[0] = 10
sl4[1] = 20
sl4[2] = 30
sl4[3] = 40
sl4[4] = 50
fmt.Println(sl4) // [10 20 30 40 50]
要素の取得
fmt.Println(sl4) // [10 20 30 40 50]
// indexを指定して取得
fmt.Println(sl4[2]) // 30
// index >= 1 && index < 3 の要素を取得
fmt.Println(sl4[1:3]) // [20 30]
// すべての要素を取得
fmt.Println(sl4[:]) // [10 20 30 40 50]
// 最後の要素を取得
fmt.Println(sl4[len(sl4)-1]) // 50
// index < 2 の要素を取得
fmt.Println(sl4[:2]) // [10 20]
// index >= 2 の要素を取得
fmt.Println(sl4[2:]) // [30 40 50]
-
スライスに要素を追加する関数
-
append: 要素の追加
append
sl := []string{"cat", "coyote", "giraffe"}
// append(スライス, 追加する値)
sl = append(sl, "bird")
fmt.Println(sl) // [cat coyote giraffe bird]
// 引数に複数の値を渡せる
sl = append(sl, "elephant", "alligator", "lion")
fmt.Println(sl) // [cat coyote giraffe bird elephant alligator lion]
- スライスのコピー
sliceは参照型であり、参照型の場合、以下のように単純に新しい変数に代入してコピーすると、
メモリ上のアドレスは同じ場所を指すため、どちらか片方を更新するともう一方にも反映される。
func main() {
sl := []int{10, 20, 30}
sl2 := sl
fmt.Println(sl2) // [10 20 30]
sl[0] = 999
fmt.Println(sl) // [999 20 30]
fmt.Println(sl2) // [999 20 30]
}
そのため、スライスのコピーにはcopy関数を使う。
copy
func main() {
sl3 := []string{"A", "B", "C", "D"}
sl4 := make([]string, 4, 8)
// copy(コピー先, コピー元)、コピーに成功した要素数を返す
num := copy(sl4, sl3)
fmt.Println(num, sl4) // 4 [A B C D]
sl3[0] = "E"
// sl3 のみ更新される
fmt.Println(sl3) // [E B C D]
fmt.Println(sl4) // [A B C D]
}
- 可変長引数
...を付けることで、引数に渡す値の数を可変にできる
func VariableLen(i ...int) int {
var num int
for _, v := range i {
num += v
}
return num
}
func main() {
r := VariableLen(1, 2, 3)
fmt.Println(r) // 6
// 引数の数を変えられる
rr := VariableLen(1, 2, 3, 4, 5)
fmt.Println(rr) // 15
// スライスも渡せる
sl := []int{10, 20, 30}
fmt.Println(VariableLen(sl...)) // 60
}
マップ
key value形式の配列。
宣言
var m = map[string]int{"A": 10, "B": 20}
fmt.Println(m) // map[A:10 B:20]
m2 := map[string]int{"A": 10, "B": 20}
fmt.Println(m2) // map[A:10 B:20]
// {}を改行する場合
m3 := map[string]int{
"A": 10,
"B": 20, // 最後の要素の後にも , が必要
}
fmt.Println(m3) // map[A:10 B:20]
要素の代入
var m = map[string]int{"A": 10, "B": 20}
m["A"] = 100
m["C"] = 30
fmt.Println(m) // map[A:100 B:20 C:30]
要素の取得
var m = map[string]int{"A": 10, "B": 20}
// mapのindexを指定すればOK
fmt.Println(m4["B"]) // 20
// 存在しないkeyでもvalueの初期値が取得できてしまう
fmt.Println(m4["D"]) // 0
// 2つ目の戻り値にboolが入ってくるため、これで判定してエラーハンドリングができる
v, ok := m["D"]
if ok {
fmt.Println(v)
} else {
fmt.Println("error")
}
要素の削除
var m = map[string]int{"A": 10, "B": 20}
// delete関数 → delete(map, index)
delete(m, "A")