if
ifは条件式がtrueのとき、続くブロックを実行します。else ifとelseで別の条件やそれ以外の処理を続けられます。
if x < 0 {
return -x
} else if x == 0 {
return 0
}
return xifキーワードのあと、条件式の前に;で区切った初期化文を書けます。初期化文で宣言した変数のスコープは、そのif文全体(各else if / elseを含む)に及びます。ブロックの外では使えず、関数全体で使えるわけではありません。
if n, err := strconv.Atoi(s); err != nil {
return err
} else {
fmt.Println(n) // n はここまで有効
}
// fmt.Println(n) // コンパイルエラーエラー処理では、成功パスに進む前にerrをチェックします。ifの本体がreturnやbreakで終わるとき、不要なelseを省略するのが慣習です。
f, err := os.Open(name)
if err != nil {
return err
}
codeUsing(f)for
Goにはwhileがありません。ループはforのみです。書き方は次の4通りです。
初期化・条件・後処理
初期化文、条件式、後処理を;で区切って並べます。3つそろえた基本形です。
for i := 0; i < 10; i++ {
fmt.Println(i)
}条件のみ
初期化と後処理を省略し、条件式だけを書きます。条件がtrueの間、本体を繰り返します。
for n < 100 {
n *= 2
}条件なし
条件式を書かないと、本体を終了しない限り繰り返します。breakやreturnで抜けます。
for {
if done {
break
}
}range
配列、スライス、文字列、マップ、チャネルを走査します。2変数形式では添字(またはキー)と値を受け取ります。マップの走査順は不定です。
for i, v := range slice {
fmt.Println(i, v)
}整数nに対するfor i := range n(Go 1.22以降)は、0からn-1までを順に取り出します。
for i := range 3 {
fmt.Println(i) // 0 1 2
}breakとcontinue
breakは最も内側のfor・switch・selectを抜けます。continueは最も内側のforの次の反復へ進みます。
for i := 0; i < 5; i++ {
if i%2 == 0 {
continue
}
if i > 3 {
break
}
fmt.Println(i) // 1 3
}switch
switchは式の値に応じて、一致したcaseの本体を実行します。どのcaseにも当てはまらないときはdefaultが実行されます。
switch day {
case "Mon":
fmt.Println("月曜")
case "Tue", "Wed":
fmt.Println("火〜水")
default:
fmt.Println("その他")
}1つのcaseにカンマ区切りで複数の値を並べると、いずれかに一致したときその本体が選ばれます。
各caseの本体を実行したあと、switchは自動的に抜けます。次のcaseへ処理を続けたいときだけ、本体の末尾にfallthroughを書きます。fallthroughは直後のcaseの本体も実行し、そのcaseでもfallthroughがなければそこでswitchを抜けます。
switch rank {
case 1:
fmt.Println("金")
fallthrough
case 2:
fmt.Println("銀")
case 3:
fmt.Println("銅")
}
// rank=1 → 金, 銀(fallthrough で case 2 も実行)
// rank=2 → 銀
// rank=3 → 銅式を書かないswitchは、各caseの条件式を上から順に評価する分岐です。最初にtrueになったcaseの本体が実行されます。
switch {
case x < 0:
fmt.Println("負")
case x == 0:
fmt.Println("ゼロ")
default:
fmt.Println("正")
}switchキーワードのあと、式の前に;で区切った初期化文を付けられます。宣言した変数のスコープは、そのswitch文全体です。
switch n, err := strconv.Atoi(input); {
case err != nil:
fmt.Println("invalid")
case n == 0:
fmt.Println("zero")
default:
fmt.Println(n) // n は switch 全体で有効
}
// fmt.Println(n) // コンパイルエラー型スイッチ
インターフェース値の動的型で分岐します。switchで宣言した変数のスコープは、そのswitch文全体です(if初期化と同様)。
func describe(x any) {
switch v := x.(type) {
case int:
fmt.Println("int", v)
case string:
fmt.Println("string", v)
default:
fmt.Println("other", v)
}
}