Go言語の制御構文
2026/07/28

if

ifは条件式がtrueのとき、続くブロックを実行します。else ifelseで別の条件やそれ以外の処理を続けられます。

if x < 0 {
    return -x
} else if x == 0 {
    return 0
}
return x

ifキーワードのあと、条件式の前に;で区切った初期化文を書けます。初期化文で宣言した変数のスコープは、そのif文全体(各else if / elseを含む)に及びます。ブロックの外では使えず、関数全体で使えるわけではありません。

if n, err := strconv.Atoi(s); err != nil {
    return err
} else {
    fmt.Println(n) // n はここまで有効
}
// fmt.Println(n) // コンパイルエラー

エラー処理では、成功パスに進む前にerrをチェックします。ifの本体がreturnbreakで終わるとき、不要な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
}

条件なし

条件式を書かないと、本体を終了しない限り繰り返します。breakreturnで抜けます。

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は最も内側のforswitchselectを抜けます。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)
    }
}