プログラムは通常、上から下へと順番に実行されますが、時には条件によって処理を変えたり、同じ処理を繰り返したりする必要があります。Go言語では、そのような制御を行うために if
文、for
文、switch
文が用意されています。これらを使いこなして、より柔軟なプログラムを作成しましょう!
if文:条件による分岐
if
文は、指定した条件が真 (true
) か偽 (false
) かによって、実行する処理を分岐させます。
基本的なif文
条件式が true
の場合に、続くブロック { }
内の処理を実行します。
package main
import "fmt"
func main() { score := 85 if score > 80 { fmt.Println("素晴らしい!合格です! ") // score > 80 が true なので実行される }
}
if-else文
条件式が true
の場合と false
の場合で、それぞれ異なる処理を実行します。
package main
import "fmt"
func main() { age := 18 if age >= 20 { fmt.Println("成人です。") } else { fmt.Println("未成年です。") // age >= 20 が false なのでこちらが実行される }
}
if-else if-else文
複数の条件で分岐させたい場合に使用します。
package main
import "fmt"
func main() { score := 75 if score >= 90 { fmt.Println("優") } else if score >= 80 { fmt.Println("良") } else if score >= 70 { fmt.Println("可") // score >= 70 が true なのでこちらが実行される } else { fmt.Println("不可") }
}
簡易ステートメント付きif文
Goの特徴的な書き方として、if
の条件式の前に簡単なステートメント(通常は変数宣言と初期化)を書くことができます。ここで宣言された変数のスコープ(有効範囲)は、if
文とその else if
/ else
ブロック内に限定されます。これはコードを簡潔にし、変数の影響範囲を狭めるのに役立ちます。
package main
import ( "fmt" "math/rand" "time"
)
func main() { // Go 1.20 より前では Seed の設定が推奨されていました // rand.Seed(time.Now().UnixNano()) // 簡易ステートメントで乱数を生成し、その値で分岐 if n := rand.Intn(10); n > 5 { fmt.Printf("%d は 5 より大きい\n", n) // 変数 n はこの if ブロック内でのみ有効 } else { fmt.Printf("%d は 5 以下\n", n) // 変数 n はこの else ブロック内でのみ有効 } // fmt.Println(n) // ここでは n は使えない (スコープ外)
}
if
(および関連する else if
/else
) ブロック内に限定されます。 for文:繰り返し処理
Go言語の繰り返し処理は for
文のみで表現されます。他の言語にある while
や do-while
に相当する構文はありませんが、for
文の柔軟な書き方でそれらを表現できます。
基本形 (C言語スタイル)
初期化ステートメント、条件式、後処理ステートメントを指定します。
package main
import "fmt"
func main() { sum := 0 // 1から10までの合計を計算 for i := 1; i <= 10; i++ { // 初期化; 条件; 後処理 sum += i } fmt.Println("合計:", sum) // 合計: 55
}
条件のみ (whileスタイル)
条件式のみを指定すると、その条件が true
である間、繰り返し処理を実行します。
package main
import "fmt"
func main() { n := 1 // nが100未満の間、2倍し続ける for n < 100 { n *= 2 } fmt.Println("結果:", n) // 結果: 128
}
無限ループ
条件式を省略すると無限ループになります。ループを抜けるには break
文を使用します。
package main
import ( "fmt" "time"
)
func main() { count := 0 for { // 無限ループ fmt.Println("ループ中...") time.Sleep(500 * time.Millisecond) count++ if count >= 3 { fmt.Println("ループを抜けます。") break // countが3以上になったらループを終了 } }
}
ループ内の特定の回の残りの処理をスキップして次のイテレーションに進むには continue
文を使用します。
for range ループ
スライス、配列、マップ、文字列、チャンネルなど、反復可能なデータ構造の要素を順番に取り出すのに便利です。
package main
import "fmt"
func main() { // スライスの例 nums := []int{10, 20, 30} sum := 0 // インデックス(i)と値(num)を取得 for i, num := range nums { fmt.Printf("インデックス: %d, 値: %d\n", i, num) sum += num } fmt.Println("スライスの合計:", sum) // 値だけ必要な場合 (インデックスを無視) sum = 0 for _, num := range nums { // インデックスを _ で破棄 sum += num } fmt.Println("スライスの合計 (値のみ):", sum) // マップの例 kvs := map[string]string{"a": "Apple", "b": "Banana"} // キー(k)と値(v)を取得 for k, v := range kvs { fmt.Printf("%s -> %s\n", k, v) } // キーだけ必要な場合 for k := range kvs { fmt.Println("キー:", k) } // 文字列の例 (rune単位で反復) for i, r := range "Go言語" { fmt.Printf("%d: %c\n", i, r) // iはバイト単位のインデックス, rはrune(文字) }
}
for range
ループ内で取得した変数はループ全体で同じメモリアドレスを指していましたが、Go 1.22からは各イテレーションで新しい変数が作られるように挙動が変更されました。これにより、ループ変数を使ったゴルーチンなどでの意図しないバグが起こりにくくなりました。初学者の段階では大きな影響はないかもしれませんが、知っておくと良いでしょう。 switch文:多岐分岐
switch
文は、ある式の値に基づいて、複数の処理経路から一つを選んで実行します。if-else if
を重ねるよりも簡潔に書ける場合があります。Goの switch
は、一致した case
の処理が終わると自動的に switch
文を抜けます(暗黙の break
)。
基本的なswitch文
package main
import "fmt"
func main() { signal := "red" switch signal { case "red": fmt.Println("止まれ ") case "yellow": fmt.Println("注意 ") case "blue", "green": // 複数の値をまとめることも可能 fmt.Println("進め ") default: // どの case にも一致しない場合 fmt.Println("不明な信号") }
}
fallthrough
Goでは通常、case
の終わりに暗黙的な break
がありますが、意図的に次の case
の処理も実行したい場合は fallthrough
キーワードを使用します。ただし、fallthrough
の使用はコードを読みにくくすることがあるため、慎重に使いましょう。
package main
import "fmt"
func main() { num := 2 switch num { case 1: fmt.Println("1") fallthrough // 次のcaseも実行 case 2: fmt.Println("2") // ここが実行される fallthrough // さらに次のcaseも実行 case 3: fmt.Println("3") // ここも実行される default: fmt.Println("default") } // 出力: // 2 // 3
}
式なしswitch (switch true)
switch
の後に式を書かない場合、switch true
と同じ意味になり、各 case
に書かれた条件式を上から順に評価し、最初に true
になった case
の処理を実行します。これは複雑な if-else if-else
文をよりきれいに書く方法として使えます。
package main
import "fmt"
func main() { score := 88 switch { // 式を省略 (switch true と同じ) case score >= 90: fmt.Println("優") case score >= 80: fmt.Println("良") // ここが true になるので実行される case score >= 70: fmt.Println("可") default: fmt.Println("不可") }
}
switch
は、条件分岐が複数ある場合にコードを読みやすくするのに役立ちます。