Golang 入門

Go 条件分岐

条件分岐(Conditional Statements)は、プログラムに「意思決定」の能力を与え、特定の条件に応じて異なるコードパスを実行することを可能にします。Go言語では、ifelse if、そして else ステートメントが、この条件ロジックを実現するための強力なツールとなります。

本章では、Go言語でこれらの条件分岐を効率的に使用するための包括的かつ分かりやすいガイドを提供します。

1. if 文の基本

if 文は、Go言語において最も基礎的な条件制御の形式です。指定された条件が 真(true) の場合にのみ、特定のコードブロックを実行します。

1.1 基本構文

Go言語における if 文の構文は以下の通りです:

if condition {
    // conditionがtrueの場合、ここを実行
}
  • condition(条件): 最終的な計算結果が true または false になるブール式(Boolean Expression)です。注意点として、Go言語では条件式を囲む小括弧 () は不要です。
  • {}(波括弧): 条件が成立した際に実行されるコードブロックを囲みます。注意点として、左波括弧 { は必ず if と同じ行に配置する必要があります。

1.2 コード例

package main

import "fmt"

func main() {
    age := 20
    
    // ageが18以上かどうかをチェック
    if age >= 18 {
        fmt.Println("あなたは投票資格があります。")
    }
}

この例では、プログラムは age >= 18 という条件をチェックします。変数 age の値は 20 であり、条件が成立(true)するため、コンソールに「あなたは投票資格があります。」と出力されます。

2. 簡易文付きの if 文

Go言語には、非常に強力で頻繁に使われる機能があります。それは、if 文の条件判断の直前に、ローカル変数を宣言および初期化できる機能です。これは、変数がその if ロジック内でのみ必要な場合に非常に有用です。

package main

import "fmt"

func main() {
    // if文の内部でage変数を宣言・初期化し、直後に判断を行う
    if age := 20; age >= 18 {
        fmt.Println("あなたは投票資格があります。")
    }
    
    // 注意:ここではage変数にアクセスできません(スコープ外のためエラーになります)
}

この例では、age 変数は if 文の内部で宣言され、20 が代入されています。

極めて重要なポイント: この方法で宣言された変数の スコープ(Scope) は、その if コードブロック内部(関連する else ifelse ブロックを含む)に限定されます。これは非常に「イディオマティック(Goらしい)」な書き方であり、グローバルな名前空間の汚染を防ぐのに効果的です。

3. else 文

else 文は、if 文の条件が 偽(false) だった場合の「代替案」を提供します。

3.1 基本構文

if-else 文の構文は以下の通りです:

if condition {
    // 条件がtrueの場合に実行
} else {
    // 条件がfalseの場合に実行
}

3.2 コード例

package main

import "fmt"

func main() {
    age := 16
    
    if age >= 18 {
        fmt.Println("あなたは投票資格があります。")
    } else {
        fmt.Println("あなたはまだ投票資格がありません。")
    }
}

この例では、age が 18 未満であるため、if の条件は偽となります。そのため、プログラムは if ブロックをスキップして else ブロックを実行し、「あなたはまだ投票資格がありません。」と出力します。

4. else if 文

複数の異なる条件を順番にチェックする必要がある場合、else if 文が活躍します。これは複雑な意思決定シーンを処理する手法を提供します。

4.1 基本構文

if-else if-else チェーンの構文は以下の通りです:

if condition1 {
    // condition1がtrueの場合に実行
} else if condition2 {
    // condition1がfalseで、かつcondition2がtrueの場合に実行
} else {
    // 前述のすべての条件がfalseの場合に実行
}

必要に応じて else if ステートメントをいくつでも連結できます。最後の else ブロックはオプションであり、どの条件にも当てはまらない場合の「デフォルト」として機能します。

4.2 コード例

package main

import "fmt"

func main() {
    score := 75
    
    if score >= 90 {
        fmt.Println("評価: A")
    } else if score >= 80 {
        fmt.Println("評価: B")
    } else if score >= 70 {
        fmt.Println("評価: C")
    } else if score >= 60 {
        fmt.Println("評価: D")
    } else {
        fmt.Println("評価: F")
    }
}

この例では、プログラムは上から下へ順番に score 変数の値をチェックし、以下の基準に従って対応する評価を出力します:

  • >= 90: 評価 A
  • >= 80: 評価 B
  • >= 70: 評価 C(75 は 70 以上なので、この条件にマッチし、以降のチェックは停止します)
  • >= 60: 評価 D
  • その他: 評価 F

5. ネストされた if 文

ある if 文の中に別の if 文を直接配置することができます。これを ネスト(Nesting) と呼びます。より深い階層の条件ロジックを処理するために使用されます。

5.1 コード例

package main

import "fmt"

func main() {
    age := 25
    hasLicense := true
    
    if age >= 18 {
        fmt.Println("あなたは法的な運転年齢に達しています。")
        
        // ネストされたif文
        if hasLicense {
            fmt.Println("免許を持っています。合法的に運転できます。")
        } else {
            fmt.Println("免許を持っていません。まずは免許を取得してください。")
        }
        
    } else {
        fmt.Println("あなたはまだ法的な運転年齢に達していません。")
    }
}

この例では、外側の if 文がまず運転可能年齢に達しているかをチェックします。外側の条件が成立した場合にのみ、内側の if 文が免許の有無を確認します。

6. 条件分岐を書くためのベストプラクティス

高品質でメンテナンスしやすい Go コードを書くために、以下の原則に従ってください:

  • 条件はシンプルかつ明白に保つ: 複雑すぎる条件判断(&&|| が多用されているもの)は混乱を招きます。複雑な条件は、より小さく管理しやすい変数や関数に分割することを検討してください。
  • 意味のある変数名を使用する: 変数名は、その用途を明確に示すべきです。条件判断が自然言語のように読めるのが理想的です(例:if isUserLoggedIn)。
  • 深いネスト(Deep Nesting)を避ける: 何層にも重なった if 文は「アローヘッド型(矢印型)コード」と呼ばれ、非常に読みにくくなります。他の制御構造(次章で学ぶ switch 文など)を使用するか、アーリーリターン(Early Return) を用いてコードをリファクタリングし、ネストの階層を減らしてください。
  • すべての可能性を網羅する: if-else if-else チェーンが、すべての妥当なビジネスシナリオをカバーしていることを確認してください。最後の else ブロックを適切に使用して、予期しない状況やエラーの受け皿にしましょう。
  • 変数のスコープに注意する: if ステートメントのヘッダーで短縮変数宣言(:=)を使用して作成された変数は、その if/else if/else ファミリーの中だけで生存し、外部からはアクセスできないことを常に念頭に置いてください。