控制流程
Rust 的某些控制流程結構與其他程式語言不同。這些結構會用於模式配對:
if let運算式while let運算式match運算式
if let 運算式
if let 運算式可讓您根據值是否符合模式,執行不同的程式碼:
fn sleep_for(secs: f32) { let dur = if let Ok(dur) = std::time::Duration::try_from_secs_f32(secs) { dur } else { std::time::Duration::from_millis(500) }; std::thread::sleep(dur); println!("slept for {:?}", dur); } fn main() { sleep_for(-10.0); sleep_for(0.8); }
let else 運算式
如果是要配對模式並從函式傳回的常見情況,請使用 let else。如果是「其他」情況,則必須發散 (return、break 或恐慌,也就是落在區塊結尾之外的任何情況)。
fn hex_or_die_trying(maybe_string: Option<String>) -> Result<u32, String> { let s = if let Some(s) = maybe_string { s } else { return Err(String::from("got None")); }; let first_byte_char = if let Some(first_byte_char) = s.chars().next() { first_byte_char } else { return Err(String::from("got empty string")); }; if let Some(digit) = first_byte_char.to_digit(16) { Ok(digit) } else { Err(String::from("not a hex digit")) } } 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!) }
Here String::pop returns Some(c) until the string is empty, after which it will return None. The while let lets us keep iterating through all items.
This slide should take about 10 minutes.
if-let
- Unlike
match,if letdoes not have to cover all branches. This can make it more concise thanmatch. - 常見用途是在使用
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迴圈就會持續運作。 - You could rewrite the
while letloop as an infinite loop with an if statement that breaks when there is no value to unwrap forname.pop(). Thewhile letprovides syntactic sugar for the above scenario.