Let制御フロー
Rust には、他の言語とは異なる制御フロー構造がいくつかあります。これらはパターン マッチングに使用されます。
if let式let else式while let式
if let 式
if let 式 を使用すると、値がパターンに一致するかどうかに応じて異なるコードを実行できます。
use std::time::Duration;
fn sleep_for(secs: f32) {
if let Ok(duration) = Duration::try_from_secs_f32(secs) {
std::thread::sleep(duration);
println!("slept for {duration:?}");
}
}
fn main() {
sleep_for(-10.0);
sleep_for(0.8);
}
let else 式
パターンをマッチして関数から戻るという一般的なケースでは、let else を使用します。「else」ケースは発散する必要があります(return、break、パニックなど、ブロックから抜けるもの以外のすべて)。
fn hex_or_die_trying(maybe_string: Option<String>) -> Result<u32, String> {
if let Some(s) = maybe_string {
if let Some(first_byte_char) = s.chars().next() {
if let Some(digit) = first_byte_char.to_digit(16) {
Ok(digit)
} else {
return Err(String::from("not a hex digit"));
}
} else {
return Err(String::from("got empty string"));
}
} else {
return Err(String::from("got None"));
}
}
fn main() {
println!("result: {:?}", hex_or_die_trying(Some(String::from("foo"))));
}
if let に似た while let 派生物もあります。これは、パターンに照らして値をテストします。
fn main() {
let mut name = String::from("Comprehensive Rust 🦀");
while let Some(c) = name.pop() {
println!("character: {c}");
}
// (There are more efficient ways to reverse a string!)
}
ここで String::pop は、文字列が空になるまで Some(c) を返し、その後 None を返します。while let を使用すると、すべてのアイテムに対して反復処理を続行できます。
This slide should take about 10 minutes.
if-let
matchとは異なり、if letではすべての分岐を網羅する必要はないため、matchよりも簡潔になります。- 一般的な使用方法は、
Optionを操作するときにSome値を処理することです。 matchとは異なり、if letはパターン マッチングでガード節をサポートしていません。
let-else
次に示すように、if let は積み重なってしまうことがあります。let-else の構成は、このネストされたコードを平坦にする助けとなります。読みづらいバージョンを受講者向けに書き直して、受講者が変化を確認できるようにします。
書き換えたバージョンは次のとおりです。
#![allow(unused)]
fn main() {
fn hex_or_die_trying(maybe_string: Option<String>) -> Result<u32, String> {
let Some(s) = maybe_string else {
return Err(String::from("got None"));
};
let Some(first_byte_char) = s.chars().next() else {
return Err(String::from("got empty string"));
};
let Some(digit) = first_byte_char.to_digit(16) else {
return Err(String::from("not a hex digit"));
};
return Ok(digit);
}
}
while-let
- 値がパターンに一致する限り、
while letループが繰り返されることを説明します。 name.pop()でunwrapする値がない場合に中断する if ステートメントを使用して、while letループを無限ループに書き換えることができます。while letは、上記のシナリオの糖衣構文として使用できます。