if / else / if let
| 対応: | Rust 1.0(2015) |
|---|
Rustの『if』は式(expression)であり、値を返すことができます。『if let』はOptionやResultのパターンマッチを簡潔に書くための構文です。
構文
// 通常のif/else
if 条件 {
// 処理
} else if 条件2 {
// 処理
} else {
// 処理
}
// 式として使用(値を返します)
let 変数 = if 条件 { 値1 } else { 値2 };
// if let(パターンマッチ分岐)
if let パターン = 値 {
// マッチした場合の処理
} else {
// マッチしなかった場合の処理
}
if / if let 比較一覧
| 構文 | 概要 |
|---|---|
| if 条件 | bool値を評価する通常の条件分岐です。 |
| else if 条件 | 複数条件を連鎖させます。 |
| let x = if ... { } else { } | ifを式として使い、変数に値を代入します。各分岐の型を揃える必要があります。 |
| if let Some(x) = opt | OptionがSomeのときだけ処理します。matchより簡潔に書けます。 |
| if let Ok(x) = result | ResultがOkのときだけ処理します。 |
サンプルコード
『if』『else if』『else』と『if let』の基本的な使い方を確認するサンプルコードです。
sample_if_else_if_let.rs
fn classify(n: i32) -> &'static str {
if n > 0 {
"正の数"
} else if n < 0 {
"負の数"
} else {
"ゼロ"
}
}
fn main() {
// 基本的なif/else
let score = 75;
let grade = if score >= 80 {
"優"
} else if score >= 60 {
"良"
} else {
"可"
};
println!("成績: {}", grade); // 『良』と出力されます。
// if letでOptionを処理します。
let some_value: Option<i32> = Some(42);
if let Some(v) = some_value {
println!("値は{}です", v); // 『42』と出力されます。
} else {
println!("値がありません");
}
// if letでResultを処理します。
let result: Result<i32, &str> = Ok(100);
if let Ok(n) = result {
println!("成功: {}", n);
}
println!("{}", classify(5));
println!("{}", classify(-3));
}
コンパイルして実行すると次のように出力されます。
rustc if_else_if_let.rs ./if_else_if_let 成績: 良 値は42です 成功: 100 正の数 負の数
よくあるミス
よくあるミス1: if let で else を書き忘れる
『if let』は Some/Ok のときだけ処理し、None/Err のときは何もしません。「値がない場合の処理」が必要なら else を追加するか match を使います。
fn get_score(name: &str) -> Option<i32> {
if name == "Kiryu" { Some(90) } else { None }
}
fn main() {
// else を書き忘れると None のケースが無視される
if let Some(score) = get_score("Majima") {
println!("スコア: {}", score);
}
// Majima は None なので何も表示されない(意図した動作か確認が必要)
}
fn get_score(name: &str) -> Option<i32> {
if name == "Kiryu" { Some(90) } else { None }
}
fn main() {
// else で None のケースも処理する
if let Some(score) = get_score("Majima") {
println!("スコア: {}", score);
} else {
println!("スコアが見つかりません");
}
}
よくあるミス2: if 式の各分岐の型が一致しない
if を式として使う場合、全ての分岐が同じ型を返す必要があります。型が異なるとコンパイルエラーになります。
fn main() {
let score = 75;
// コンパイルエラー: 各分岐の型が異なる(i32 と &str)
// let grade = if score >= 80 { 100 } else { "良" };
}
fn main() {
let score = 75;
// OK: 全分岐が同じ型(&str)を返す
let grade = if score >= 80 {
"優"
} else if score >= 60 {
"良"
} else {
"可"
};
println!("成績: {}", grade);
}
概要
Rustのifは文ではなく式のため、三項演算子の代わりに使えます。各分岐の戻り値は同じ型でなければならず、型が一致しない場合はコンパイルエラーになります。
『if let』はOptionやResultのパターンを1つだけ処理したい場合に便利です。複数のパターンを処理する場合は『match』のほうが明確で読みやすくなります。詳細はmatch / パターンマッチを参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。