控制流程
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 let
does 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 let
loop as an infinite loop with an if statement that breaks when there is no value to unwrap forname.pop()
. Thewhile let
provides syntactic sugar for the above scenario.