Go言語(golang)のループ for, for..range, foreach, while
go言語(golang)での繰り返し処理 for文の使い方。
foreach と while については go言語に構文自体がないので、それぞれ for range と for 文を使う。
また、他の言語同様に continue でスキップ break でループ処理を抜けることができる。
目次
for文
基本的な for 文による繰り返し処理。以下の i < 5
の部分は if 文の条件式と同じで、
条件が真(true)であれば処理を続行し、偽(false)であれば処理を終了する。
for i := 0; i < 5; i++ { fmt.Println(i) // 0 // 1 // 2 // 3 // 4 }
continue を使ってループをスキップする。
以下、i が偶数の場合はスキップして i が奇数の場合のみ出力される。
for i := 0; i < 10; i++ { if i%2 == 0 { continue } fmt.Println(i) // 1 // 3 // 5 // 7 // 9 }
break を使って繰り返し処理を終了する。
以下は、i が 5 の場合にループを抜ける。
for i := 0; i < 10; i++ { if i == 5 { break } fmt.Println(i) // 0 // 1 // 2 // 3 // 4 }
多重代入で複数の変数を使った例。
for i, j := 0, 9; i < 10 && j >= 0; i, j = i+1, j-1 { fmt.Println(i, j) // 0 9 // 1 8 // 2 7 // 3 6 // 4 5 // 5 4 // 6 3 // 7 2 // 8 1 // 9 0 }
ラベルを使って内側のループで外側のループ処理を停止させる。
loop: for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { fmt.Println(i, j) // 0 0 // 0 1 // 0 2 // 1 0 // 1 1 // 1 2 if i == 1 && j == 2 { break loop } } }
while文
go言語には while 文はないので for 文で条件式のみ書く。
i := 0 for i < 10 { fmt.Println(i) i++ }
無限ループ
無限ループは以下のように書く。
for { // なんかの処理 }
無限ループでカウントを取りたい場合は、条件式なにも書かない。
for i := 0;; i++ { }
foreach (for ... range)
foreach は構文としてないので、代わりに for...range を使う。
以下 i にはループ回数が、 v には配列の値が順番に代入される。
回数が必要ない場合は for _, v := range
とアンダーバーにして破棄する。
for i, v := range []string{"foo", "bar", "baz"} { fmt.Println(i, v) // 0 foo // 1 bar // 2 baz }
map(連想配列)の場合は以下の k にキーが, v に値が順番に代入される。
for k, v := range map[string]int{"key-1": 100, "key-2": 200, "key-3": 300} { fmt.Println(k, v) // key-2 200 // key-3 300 // key-1 100 }
goto 文を繰り返し処理に使う
goto 文を使ったループの書き方。
i := 0 loop: fmt.Println(i) // 0 // 1 // 2 // 3 // 4 // 5 if i < 5 { i++ goto loop }
goto 文を使った繰り返し処理の実例。yes か no のどちらかが入力されるまで goto で繰り返す。
yes := false r := bufio.NewReader(os.Stdin) loop: fmt.Print("[yes/no]: ") input, err := r.ReadString('\n') if err != nil { log.Fatal(err) } switch strings.ToLower(strings.Trim(input, "\n")) { case "yes": yes = true case "no": default: goto loop } fmt.Println(yes)
他の言語にあるような each 関数を実装してみる
package main import "fmt" type StrSlice []string func (a StrSlice) Each(f func(i int, v string)) { for i, v := range a { f(i, v) } } type IntSlice []int func (a IntSlice) Each(f func(i int, v int)) { for i, v := range a { f(i, v) } } func main() { StrSlice{"foo", "bar", "baz"}.Each(func(i int, v string) { fmt.Println(i, v) }) IntSlice{10, 20, 30}.Each(func(i int, v int) { fmt.Println(i, v) }) }