INDEX
elseの概要
| 条件がfalseのときに実行する処理を書くGoの予約語 | ||
|
else 概要 elseは、if文の条件評価式が偽(false)と判定された場合に、代替として実行する制御フローのコードブロックを定義するために使用します。 |
||
|
elseの考え方をイメージで理解

基本的なelseの使い方(二者択一の分岐制御)
条件が真(true)であるか偽(false)であるかに応じて、実行する処理を完全に2つのルートへ分断する最も基本的なパターンです。
package main
import "fmt"
func main() {
num := 10
if num > 10 {
// 条件が真(true)の場合に実行
fmt.Println("10より大きい数値です")
} else {
// 条件が偽(false)の場合に実行
fmt.Println("10以下の数値です")
}
}
構造解説:
num > 10という評価式の型はboolです。今回numは 10 であるため、評価結果はfalse(偽)となります。- これにより、
if直後の波括弧内のコードは完全に無視され、elseにカプセル化されているブロックが代替として呼び出されます。
実行結果:
10以下の数値です
else ifを用いた多者択一の排他条件チェイン
3つ以上の境界値や状態を段階的に評価する場合、else if を間に挟むことで上から順番に条件をスキャンさせることができます。
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 {
// 上記の条件すべてが偽(false)だった場合の最終ルート
fmt.Println("評価: 不可 (D)")
}
}
構造解説:
- プログラムは最上段の
score >= 90から検証を始めます。これがfalseであるため次のelse if score >= 80へ進み、これもfalseであるためさらに次のscore >= 70へと流れます。 score >= 70で初めて条件がtrueに確定するため、該当ブロックが実行され、それ以降のelse判定は評価されずに全体の構文から離脱します。
実行結果:
評価: 可 (C)
if文の簡易文脈(短縮構文)とelseのスコープ共有
Go言語では、if 条件式の評価の前に「初期化文」をセミコロン(;)で区切って記述できます。この初期化文で生成されたローカル変数は、後ろに続く else ブロックの内部でも有効に機能します。
package main
import "fmt"
func main() {
// 変数「status」の宣言・初期化をif文のスコープ内に限定する
if status := "unauthorized"; status == "authenticated" {
fmt.Println("アクセスが許可されました。")
} else {
// if文の直前で生成された status 変数をそのまま利用可能
fmt.Printf("拒否されました。現在の状態: %s\n", status)
}
// ここで status を参照しようとするとコンパイルエラーになる
// fmt.Println(status) // error: undefined: status
}
構造解説:
status := "unauthorized"はif-else構造全体の生存期間(ライフタイム)にバインドされます。- 関数のグローバルな空間に変数を汚染させない(不要な変数を残さない)という最小権限の原則に則った、Go特有の非常にクリーンな設計パターンです。
実行結果:
拒否されました。現在の状態: unauthorized
学術的・設計的注意点
- 改行配置の強制(セミコロン自動挿入機構の制約): Go言語のソースコードでは、
elseキーワードを独立した新しい行の先頭に記述すると、コンパイルエラー(syntax error: unexpected else)になります。これはGoコンパイラが解析時に行末へ自動的にセミコロン(;)を補完する仕様(Semicolon Injection Rule)を持っているためです。}の直後に改行を入れると、コンパイラがif文の完全な終了とみなしてセミコロンを打ってしまうため、続くelseが孤立して構文エラーを引き起こします。そのため、必ず} else {を1行の連続したトークンとして記述しなければなりません。 - ガード節による「Happy Path」の維持とelse回避: ソフトウェア工学(クリーンコード)において、
elseはコードのネストを深くし、認知的複雑性を上げる原因として警戒される傾向にあります。特に関数内でエラーや例外的な条件を弾くだけの目的であれば、elseブロックの中に正常系ロジックを詰め込むのではなく、if err != nil { return }のように早期にリターン(アーリーリターン)させ、elseをあえて記述せずに正常系(Happy Path)をインデントの浅いメインストリームに残すコーディングスタイルが推奨されます。
よくある質問(FAQ)
- Q: else if を重ねるのと、switch文を使うのでは、内部の処理効率(パフォーマンス)に違いはありますか?
- A: Go言語のコンパイラは非常にスマートなため、単純な値の比較による
else ifチェインであれば、内部的にswitch文と同様に効率的なジャンプテーブル等へ最適化されるケースが多く、実行速度に致命的な差が出ることは稀です。ただし、設計思想および可読性の観点からは、同一の変数に対する多方分岐であればswitchを使い、異なる条件式や複雑な論理演算が絡む分岐であればif-else ifを使う、という書き分けが最適です。 - Q: 短縮構文(if initialization; condition)の中で既存の同名変数を宣言した場合、else側ではどちらが参照されますか?
- A:
ifの初期化文で変数を短縮型宣言(:=)した場合、既存の外側のスコープにある同名変数とは異なる、新しいローカル変数が「シャドウイング(覆い隠し)」として生成されます。当然、それに連なるelseブロックの内部でも、このシャドウイングされた(if構文内で新しく生成された)側の変数が最優先で参照されるため、意図しない値の混同を防ぐための注意が必要です。 - Q: Go言語には、他言語にある「三項演算子(condition ? trueVal : falseVal)」のような簡潔なインライン記述はないのですか?
- A: ありません。Go言語の設計者たちは「コードの可読性を最大化し、1つの目的を達成するための記述方法は常に1通りであるべきだ」という哲学(コンプレキシティの排除)を貫いたため、三項演算子の導入を意図的に見送りました。そのため、どれほど単純な二者択一であっても、必ず省略せずに
if-else構文を組み立てて記述する必要があります。
まとめ
elseは、ifに課された条件が満たされなかった場合に実行される代替制御フローを確定するための予約語。- Go言語の文法規則(セミコロン自動挿入機構)の制約上、直前の閉じ括弧と同一行(
} else {)に記述することが必須。 - 簡易文脈(初期化文)と組み合わせることで、
ifおよびelseのコードブロック内だけで閉じたカプセル精度の高い変数の取り扱いが可能。 - 過度な
else ifの累積はコードの認知的複雑性を高めるため、ガード節(早期離脱)の適用やswitch構文へのリファクタリングを適宜考慮することが重要となる。