拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Rust编程语言:控制流(Control Flow)

Rust编程语言:控制流(Control Flow)

条件分支结构

if

结构:

if condition {

} else if condition {

} else {

}

fn main() { let number = 6; if number % 4 == 0 { println!("number is divisible by 4"); } else if number % 3 == 0 { println!("number is divisible by 3"); } else if number % 2 == 0 { println!("number is divisible by 2"); } else { println!("number is not divisible by 4, 3, or 2"); } }

Rust 中 if 结构的 condition 必须是一个 bool 类型(与 Python 不同)。

fn main() { let number = 3; if number { println!("number was three"); } }

Rust 的 if 是一个表达式,可以用做赋值操作,以最后一个没有分号的表达式作为值返回,一个if 结构只会产生一个值。

fn main() { let condition = true; let number = if condition { 100 } else { 2 }; println!("The value of number is: {number}"); }

每个if 结构的所有分支的返回类型必须相同。

fn main() { let condition = true; let number = if condition { 100 } else { "x" }; println!("The value of number is: {number}"); }

没有显式返回时,返回类型为元组()。

fn main() { let condition = true; let number = if condition { 100 } else { }; }

match

基本结构

match 值 {
模式1 => 表达式1,
模式2 => 表达式2,
_ => 默认表达式,
}

enum Coin { Penny, Nickel, Dime, Quarter, } fn value_in_cents(coin: Coin) -> u8 { match coin { Coin::Penny => 1, Coin::Nickel => 5, Coin::Dime => 10, Coin::Quarter => 25, } }

Rust 要求 match 的分支必须穷举被匹配对象所有可能的值(Matches Are Exhaustive)来提高安全性,防止开发者遗漏。

Rust 使用 _ 占位符表示剩余情况。

fn main() { let dice_roll = 9; match dice_roll { 3 => println!("3"), 7 => println!("7"), _ => println!("no dice roll"), } }

if let

match 语法是穷举的,所以如果你仅只想匹配一种模式,也要使用 _。

fn main() { let config_max = Some(3u8); match config_max { Some(max) => println!("The maximum is configured to be {max}"), _ => (), } }

这就显得很臃肿了,为此,Rust 提供了if let 语法,上面的代码等价于:

fn main() { let config_max = Some(3u8); if let Some(max) = config_max { println!("The maximum is configured to be {max}"); } }

注意:if let 只能用于模式匹配,不能用于 先赋值 再做bool 判断(与 Python 不同),比如:

fn main() { let c = [1, 2, 3, 4, 5]; if let a = c[0] == 2 { println!("hello,world!"); } }

猜猜会输出什么?

了解过python的读者可能会这么理解这个条件:

  • 先把c[0] 赋值给变量a
  • 判断a是否等于2
  • 由于c[0] 等于1,所以条件为假,不执行打印语句。

看下结果:

【hello,world!】居然输出出来了。这恰恰证明了Rust不支持像Python语言的海象操作符那样的运算。

实际上逻辑是这样的,

if let后面写的是模式匹配,a是一个“总能匹配成功”的变量模式,所以它本身没有筛选条件。

真正执行到这里时:

  • c[0] == 2会先被计算成一个布尔值
  • 结果是false
  • 然后false也能被a这个模式匹配上
  • 所以if代码块一定会执行

所以:

  • 表面上看像条件:c[0] == 2
  • 实际上的条件:没有条件,if let a = ...这种写法基本等价于“把右边的值绑定给 a,然后进入代码块”,代码块中的代码会无条件执行!!

循环结构

break

跳出某个循环(默认跳出 break 所在的循环)

continue

跳过本轮,进入下一轮

loop

Rust 设计了 loop 关键字(很有古韵)。

fn main() { loop { println!("again!"); } }

Rust 的 loop 是一个expression 可以返回值。

fn main() { let mut counter = 0; let result = loop { counter += 1; if counter == 10 { break counter * 2; } }; println!("The result is {result}"); }

while

while 实际上就是 loop ,if,和break搭配使用的结果。

fn main() { let mut number = 3; while number != 0 { println!("{number}!"); number -= 1; } println!("LIFTOFF!!!"); }

等价于:

fn main() { let mut number = 3; loop { if number == 0 { break; } println!("{number}!"); number -= 1; } println!("LIFTOFF!!!"); }

for

Rust 没有C/Java/Go风格的for循环遍历,均是迭代器循环。

for 模式 in 迭代器 {
循环体
}

基本用法:

fn main() { // 左闭右开 // 正序 for i in 0..10 { println!("{}",i); } // 倒序 for i in (0..10).rev() { println!("{}",i); } }

loop labels

Rust 的三种循环loop、while、for都可以使用循环标签(label),而且标签语法完全一致。

'label: loop { ... }
'label: while cond { ... }
'label: for x in iter { ... }

可以搭配 break 实现跳出指定循环的效果。

fn main() { let mut count = 0; 'counting_up: loop { println!("count = {count}"); let mut remaining = 10; loop { println!("remaining = {remaining}"); if remaining == 9 { break; } if count == 2 { break 'counting_up; } remaining -= 1; } count += 1; } println!("End count = {count}"); }
返回列表