はじめに
船井総研デジタルのoswです。業務でGo言語を使うことになったのでこれから学習していきます。その備忘録です。参考になる方がいらっしゃれば幸いです。
対象読者
- これからGo言語を学習する方
- 既に他の言語で基本構文を学習されている方
学習環境
学習環境は次のようになっています。この環境の構築メモは下記記事にまとめてあります。ご興味がある方はご参照ください。
- Windows 11 Home / 22H2
- VSCode / 1.72.2
- go version go1.19.2 windows/amd64
- git version 2.38.0.windows.1
前回までの学習
前回は演算子、制御構文などを学習しました。
繰り返し
for文
Goには繰り返し構文として用意されているのはforしかないようです。書き方にバリエーションを付けることでwhileのように使い、無限ループにすることもできます。if同様、{}は必須です。()は付けるとコンパイルエラーになってしまうようです。
// 条件が満たされている限り繰り返す
for 初期値; 繰り返し条件; 更新処理 {
// 処理
}
// 省略形for文
for 繰り返し条件 {
// 処理
}
// 無限ループ
for {
// 処理
}
package main
import "fmt"
func main() {
fmt.Println("通常for文")
for i := 0; i < 5; i++ {
fmt.Println("i:", i)
}
fmt.Println("\n省略形for文")
k := 0
for k < 5 {
fmt.Println("k:", k)
k++
}
fmt.Println("\n無限ループ")
j := 0
for {
fmt.Println("j:", j)
if j == 4 {
break
}
j++
}
// ()をつけるとコンパイルエラー
// for (i := 0; i < 5; i++) {
// fmt.Println("i:", i)
// }
}
通常for文
i: 0
i: 1
i: 2
i: 3
i: 4
省略形for文
k: 0
k: 1
k: 2
k: 3
k: 4
無限ループ
j: 0
j: 1
j: 2
j: 3
j: 4
break / continue / goto
これらは他の言語同様の働きをします。breakは現在のループ、switch文を抜けます。continueは現在のループ処理を中断し、次のループに移行します。gotoもあります。
package main
import "fmt"
func main() {
fmt.Println("breakの動作確認")
for i := 0; i < 5; i++ {
if i == 3 {
break
}
fmt.Println("i:", i)
}
fmt.Println("\ncontinueの動作確認")
for i := 0; i < 5; i++ {
if i%2 == 0 {
continue
}
fmt.Println("i:", i)
}
fmt.Println("\ngotoの動作確認")
for i := 0; i < 5; i++ {
if i == 3 {
goto Goto
}
fmt.Println("i:", i)
}
return
Goto:
fmt.Println("ジャンプ")
}
breakの動作確認
i: 0
i: 1
i: 2
continueの動作確認
i: 1
i: 3
gotoの動作確認
i: 0
i: 1
i: 2
ジャンプ
ラベルの働き
Goではgoto以外にもラベル付けることができるようです。goto以外は実行した位置より外のスコープ、かつ上の行にラベルを記述します。指定した位置に飛ぶとgotoになってしまうのでそういう書き方になっているんでしょうか。
直感的に少々わかりづらいですが、ラベルはforに「紐づき」、breakなら紐づいたforを抜ける、continueなら紐づいたforから処理を再開、という動作になるようです。
// ラベル1は直後の、外側のforと紐づく
ラベル1:
for {
for {
break ラベル1
}
}
// 「紐づいたfor」を抜けるため、break後の制御はここに移る
// ラベル2は直後の、外側のforと紐づく
ラベル2:
for i := 0; i < 5; i++ {
// 「紐づいたfor」に戻るため、continue後の制御はここに移る
// 外側forのカウンタを更新し、処理を再開
for {
continue ラベル2
}
}
package main
import "fmt"
func main() {
const loopNum = 3
fmt.Println("BreakLoop")
BreakLoop:
// fmt.Println("ラベルとforの間にコードを書いてはいけない") コンパイルエラー
for i := 0; i < loopNum; i++ {
for j := 0; j < loopNum; j++ {
if j == 1 {
break BreakLoop
}
fmt.Println("i:", i, ", j:", j)
}
}
fmt.Println("\nContinueLoop")
ContinueLoop:
// fmt.Println("ラベルとforの間にコードを書いてはいけない") コンパイルエラー
for i := 0; i < loopNum; i++ {
for j := 0; j < loopNum; j++ {
if j == 1 {
continue ContinueLoop
}
fmt.Println("i:", i, ", j:", j)
}
}
}
BreakLoop
i: 0 , j: 0
ContinueLoop
i: 0 , j: 0
i: 1 , j: 0
i: 2 , j: 0
おわりに
今回はここまでです。