表达式

Rust 主要是一个基于表达式的语言。只有两种语句,其它的一切都是表达式。

表达式返回一个值,而语句不是。这就是为什么这里我们以“不是所有控制路径都返回一个值”。Rust 中有两种类型的语句:“声明语句”和“表达式语句”。其余的一切是表达式。

在 Rust 中,使用let引入一个绑定并不是一个表达式。下面的代码会产生一个编译时错误:

  1. let x = (let y = 5); // expected identifier, found keyword `let`

编译器告诉我们这里它期望看到表达式的开头,而let只能开始一个语句,不是一个表达式。

注意赋值一个已经绑定过的变量(例如,y = 5)仍是一个表达式,即使它的(返回)值并不是特别有用。不像其它语言中赋值语句返回它赋的值(例如,前面例子中的5),在 Rust 中赋值的值是一个空的元组()

  1. let mut y = 5;
  2. let x = (y = 6); // x has the value `()`, not `6`

Rust中第二种语句是表达式语句。它的目的是把任何表达式变为语句。Rust 语法期望语句后跟其它语句。用分号来分隔各个表达式.

控制结构

  • return
  • if/if let
  • while/while let
  • loop
  • for
  • label
  • break 与 continue
  • match

return

  1. fn max(a: i32, b: i32) -> i32 {
  2. if a > b {
  3. return a;
  4. }
  5. return b;
  6. }

If

if 语句是分支这个更加宽泛的概念的一个特定形式。 Rust 的 if 表达式的显著特点是:1,判断条件不用小括号括起来;2,它是表达式,而不是语句。

  1. let x = 5;
  2. if x == 5 {
  3. println!("x is five!");
  4. }

如果if后面的表达式的值为true,这个代码块将被执行。为false则不被执行。

如果你想当值为false时执行些什么,使用else

  1. let x = 5;
  2. if x == 5 {
  3. println!("x is five!");
  4. } else {
  5. println!("x is not five :(");
  6. }

如果不止一种情况,使用else if

  1. let x = 5;
  2. if x == 5 {
  3. println!("x is five!");
  4. } else if x == 6 {
  5. println!("x is six!");
  6. } else {
  7. println!("x is not five or six :(");
  8. }

你可以(或许也应该)这么写:

  1. let x = 5;
  2. let y = if x == 5 { 10 } else { 15 }; // y: i32

这代码可以被执行是因为if是一个表达式。表达式的值是任何被选择的分支的最后一个表达式的值。一个没有elseif总是返回()作为返回值。

if let模式 : match 的简化用法

  1. let dish = ("Ham", "Eggs");
  2. // this body will be skipped because the pattern is refuted
  3. if let ("Bacon", b) = dish {
  4. println!("Bacon is served with {}", b);
  5. } else {
  6. // This block is evaluated instead.
  7. println!("No bacon will be served");
  8. }
  9. // this body will execute
  10. if let ("Ham", b) = dish {
  11. println!("Ham is served with {}", b);
  12. }
  1. fn main() {
  2. let favorite_color: Option<&str> = None;
  3. let is_tuesday = false;
  4. let age: Result<u8, _> = "34".parse();
  5. if let Some(color) = favorite_color {
  6. println!("Using your favorite color, {}, as the background", color);
  7. } else if is_tuesday {
  8. println!("Tuesday is green day!");
  9. } else if let Ok(age) = age {
  10. if age > 30 {
  11. println!("Using purple as the background color");
  12. } else {
  13. println!("Using orange as the background color");
  14. }
  15. } else {
  16. println!("Using blue as the background color");
  17. }
  18. }

Rust 目前提供一些迭代操作。他们是loopwhilefor。每种方法都有自己的用途

loop

Rust 提供的循环执行,使用loop关键字。

  1. loop {
  2. println!("Loop forever!");
  3. }

while

Rust 提供的条件执行。

  1. let mut x = 5; // mut x: i32
  2. let mut done = false; // mut done: bool
  3. while !done {
  4. x += x - 3);
  5. println!("{}", x);
  6. if x % 5 == 0 {
  7. done = true;
  8. }
  9. }

while let模式

  1. let mut stack = Vec::new();
  2. stack.push(1);
  3. stack.push(2);
  4. stack.push(3);
  5. while let Some(top) = stack.pop() {
  6. println!("{}", top);
  7. }

for

Rust 提供的遍历执行。

  1. for x in 0..10 {
  2. println!("{}", x); // x: i32
  3. }
  4. let v = vec!['a', 'b', 'c'];
  5. for (index, value) in v.iter().enumerate() {
  6. println!("{} is at index {}", value, index);
  7. }

更抽象的形式:

  1. for var in expression {
  2. code
  3. }

这个表达式是一个迭代器.迭代器返回一系列的元素。0..10表达式取一个开始和结束的位置,然后给出一个含有这之间值得迭代器。它不包括上限值,所以我们的循环会打印09

Enumerate方法

当你需要记录你已经循环了多少次了的时候,你可以使用.enumerate()函数。

对范围(On ranges):

  1. for (i,j) in (5..10).enumerate() {
  2. println!("i = {} and j = {}", i, j);
  3. }

输出:

  1. i = 0 and j = 5
  2. i = 1 and j = 6
  3. i = 2 and j = 7
  4. i = 3 and j = 8
  5. i = 4 and j = 9

对迭代器(On iterators)

  1. let lines = "hello\nworld".lines();
  2. for (linenumber, line) in lines.enumerate() {
  3. println!("{}: {}", linenumber, line);
  4. }

输出:

  1. 0: hello
  2. 1: world

提早结束迭代

让我们再看一眼之前的while循环:

  1. let mut x = 5;
  2. let mut done = false;
  3. while !done {
  4. x += x - 3;
  5. println!("{}", x);
  6. if x % 5 == 0 {
  7. done = true;
  8. }
  9. }

我们必须使用一个mut布尔型变量绑定,done,来确定何时我们应该推出循环。

Rust 有两个关键字帮助我们来修改迭代:breakcontinue

  • break 用来跳出当前层的循环;
  • continue 用来执行当前层的下一次迭代。
  1. let mut x = 5;
  2. loop {
  3. x += x - 3;
  4. println!("{}", x);
  5. if x % 5 == 0 { break; }
  6. }

现在我们用loop来无限循环,然后用break来提前退出循环。

continue比较类似,不过不是退出循环,它直接进行下一次迭代。下面的例子只会打印奇数:

  1. for x in 0..10 {
  2. if x % 2 == 0 { continue; }
  3. println!("{}", x);
  4. }

breakcontinuewhile循环和for循环中都有效。

循环标签(Loop labels)

你也许会遇到这样的情形,当你有嵌套的循环而希望指定你的哪一个breakcontinue该起作用。就像大多数语言,默认breakcontinue将会作用于最内层的循环。当你想要一个breakcontinue作用于一个外层循环,你可以使用标签来指定你的breakcontinue语句作用的循环。如下代码只会在xy都为奇数时打印他们:

  1. 'outer: for x in 0..10 {
  2. 'inner: for y in 0..10 {
  3. if x % 2 == 0 { continue 'outer; } // continues the loop over x
  4. if y % 2 == 0 { continue 'inner; } // continues the loop over y
  5. println!("x: {}, y: {}", x, y);
  6. }
  7. }