let 控制流
Rust 有几个与其他语言不同的控制流结构。它们用于模式匹配:
if let表达式while letexpressionsmatch表达式
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 expressions
如需了解匹配模式并从函数返回的常见情况,请使用 let else。”else” 分支必须执行不同的结束方式(例如,return、break 或 panic,但不能直接执行到代码块的末尾)。
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.
if-let
- Unlike
match,if letdoes not have to cover all branches. This can make it more concise thanmatch. - 使用
Option时,常见的做法是处理Some值。 - 与
match不同的是,if let不支持模式匹配的 guard 子句。
let-else
if-lets can pile up, as shown. The let-else construct supports flattening this nested code. Rewrite the awkward version for students, so they can see the transformation.
重写后的版本为:
#![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.