if let

if let によってiflet を一体化して用いることが可能となり、 ある種のパターンマッチに伴うオーバーヘッドを削減することができます。

例えば今、 Option<T> 型の値が有るとして、 この値が Some<T> であるならば何らかの関数を呼び出し、None ならば何もしたくないとしましょう そのような処理は例えば以下のように書けるでしょう:

fn main() { let option = Some(5); fn foo(x: i32) { } match option { Some(x) => { foo(x) }, None => {}, } }
match option {
    Some(x) => { foo(x) },
    None => {},
}

このような場合 match を用いなくても良く、 if を使って以下のように書けます:

fn main() { let option = Some(5); fn foo(x: i32) { } if option.is_some() { let x = option.unwrap(); foo(x); } }
if option.is_some() {
    let x = option.unwrap();
    foo(x);
}

上述のコードのどちらもまだ理想的ではありません。 if let を用いてより良い方法で記述できます:

fn main() { let option = Some(5); fn foo(x: i32) { } if let Some(x) = option { foo(x); } }
if let Some(x) = option {
    foo(x);
}

もし パターン マッチが成功した場合、パターンに含まれる変数に適切に値が割り当てられ、 式が評価されます。もしパターンマッチが失敗した場合には何も起こりません。

もしパターンマッチに失敗した場合に実行したいコードが有る場合は else を使うことができます:

fn main() { let option = Some(5); fn foo(x: i32) { } fn bar() { } if let Some(x) = option { foo(x); } else { bar(); } }
if let Some(x) = option {
    foo(x);
} else {
    bar();
}

while let

同じように、 while let を使うことで、値がパターンにマッチし続ける限り繰り返し実行することができます。 例えば以下の様なコードが有るときに:

fn main() { let mut v = vec![1, 3, 5, 7, 11]; loop { match v.pop() { Some(x) => println!("{}", x), None => break, } } }
let mut v = vec![1, 3, 5, 7, 11];
loop {
    match v.pop() {
        Some(x) =>  println!("{}", x),
        None => break,
    }
}

while let を用いることで、以下のように書くことができます:

fn main() { let mut v = vec![1, 3, 5, 7, 11]; while let Some(x) = v.pop() { println!("{}", x); } }
let mut v = vec![1, 3, 5, 7, 11];
while let Some(x) = v.pop() {
    println!("{}", x);
}