Конструкция if let
Иногда хочется сделать определённые вещи менее неуклюже. Например,
скомбинировать if
и let
чтобы более удобно сделать сопоставление с образцом.
Для этого есть if let
.
В качестве примера рассмотрим Option<T>
. Если это Some<T>
, мы хотим вызвать
функцию на этом значении, а если это None
— не делать ничего. Вроде такого:
# let option = Some(5);
# fn foo(x: i32) { }
match option {
Some(x) => { foo(x) },
None => {},
}
Здесь необязательно использовать match
. if
тоже подойдёт:
# let option = Some(5);
# fn foo(x: i32) { }
if option.is_some() {
let x = option.unwrap();
foo(x);
}
Но оба этих варианта выглядят странно. Мы можем исправить это с помощью if let
:
# let option = Some(5);
# fn foo(x: i32) { }
if let Some(x) = option {
foo(x);
}
Если сопоставление с образцом успешно, имена в образце связываются с соответствующими частями разбираемого значения, и блок исполняется. Если значение не соответствует образцу, ничего не происходит.
Если вы хотите делать что-то ещё при несовпадении с образцом, используйте
else
:
# let option = Some(5);
# fn foo(x: i32) { }
# fn bar() { }
if let Some(x) = option {
foo(x);
} else {
bar();
}
while let
Похожим образом, while let
можно использовать для перебора значений, пока
они соответствуют образцу. Код вроде такого:
# let option: Option<i32> = None;
loop {
match option {
Some(x) => println!("{}", x),
_ => break,
}
}
Превращается в такой:
# let option: Option<i32> = None;
while let Some(x) = option {
println!("{}", x);
}