|
|
@ -38,7 +38,7 @@ if let PATTERN = SOME_VALUE {
|
|
|
|
```
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### while let条件循环
|
|
|
|
#### while let条件循环
|
|
|
|
一个与 `if let` 结构类似的是 `while let` 条件循环,它允许只要模式匹配就一直进行 `while` 循环。下面展示了一个使用`while let`的例子:
|
|
|
|
一个与 `if let` 类似的结构是 `while let` 条件循环,它允许只要模式匹配就一直进行 `while` 循环。下面展示了一个使用`while let`的例子:
|
|
|
|
```rust
|
|
|
|
```rust
|
|
|
|
// Vec是动态数组
|
|
|
|
// Vec是动态数组
|
|
|
|
let mut stack = Vec::new();
|
|
|
|
let mut stack = Vec::new();
|
|
|
@ -54,9 +54,9 @@ while let Some(top) = stack.pop() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
这个例子会打印出 `3`、`2` 接着是 `1`。`pop` 方法取出动态数组的最后一个元素并返回 `Some(value)`,如果动态数组是空的,它返回 `None`。对于`while`来说,只要 `pop` 返回 `Some` 就会一直不停的循环。一旦其返回 `None`,`while` 循环停止。我们可以使用 `while let` 来弹出栈中的每一个元素。
|
|
|
|
这个例子会打印出 `3`、`2` 接着是 `1`。`pop` 方法取出动态数组的最后一个元素并返回 `Some(value)`,如果动态数组是空的,将返回 `None`,对于`while`来说,只要 `pop` 返回 `Some` 就会一直不停的循环。一旦其返回 `None`,`while` 循环停止。我们可以使用 `while let` 来弹出栈中的每一个元素。
|
|
|
|
|
|
|
|
|
|
|
|
你也可以用`loop` + `if let` 或者`match`来实现,但是会更加啰嗦。
|
|
|
|
你也可以用`loop` + `if let` 或者`match`来实现这个功能,但是会更加啰嗦。
|
|
|
|
|
|
|
|
|
|
|
|
#### for循环
|
|
|
|
#### for循环
|
|
|
|
```rust
|
|
|
|
```rust
|
|
|
@ -67,18 +67,18 @@ for (index, value) in v.iter().enumerate() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
这里使用 `enumerate` 方法产生一个迭代器,该迭代器每次迭代会返回一个`(索引,值)`形式的元组,同时用`(index,value)`来匹配。
|
|
|
|
这里使用 `enumerate` 方法产生一个迭代器,该迭代器每次迭代会返回一个`(索引,值)`形式的元组,然后用`(index,value)`来匹配。
|
|
|
|
|
|
|
|
|
|
|
|
#### let语句
|
|
|
|
#### let语句
|
|
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
```rust
|
|
|
|
let PATTERN = EXPRESSION;
|
|
|
|
let PATTERN = EXPRESSION;
|
|
|
|
```
|
|
|
|
```
|
|
|
|
是的, 该语句我们已经用了无数次了,它也是一种模式匹配:
|
|
|
|
是的, 该语句我们已经用了无数次了,它也是一种模式匹配:
|
|
|
|
```rust
|
|
|
|
```rust
|
|
|
|
let x = 5;
|
|
|
|
let x = 5;
|
|
|
|
```
|
|
|
|
```
|
|
|
|
这其中,`x`也是一种模式绑定,代表将**匹配的值绑定到变量x上**.因此,在Rust中,**变量名也是一种模式**,只不过它比较朴素很不起眼罢了。
|
|
|
|
这其中,`x`也是一种模式绑定,代表将**匹配的值绑定到变量x上**。因此,在Rust中,**变量名也是一种模式**,只不过它比较朴素很不起眼罢了。
|
|
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
```rust
|
|
|
|
let (x, y, z) = (1, 2, 3);
|
|
|
|
let (x, y, z) = (1, 2, 3);
|
|
|
@ -86,11 +86,11 @@ let (x, y, z) = (1, 2, 3);
|
|
|
|
|
|
|
|
|
|
|
|
上面将一个元组与模式进行匹配(**模式和值的类型必需相同!**),然后把`1,2,3`分别绑定到`x,y,z`上。
|
|
|
|
上面将一个元组与模式进行匹配(**模式和值的类型必需相同!**),然后把`1,2,3`分别绑定到`x,y,z`上。
|
|
|
|
|
|
|
|
|
|
|
|
因为模式匹配要求两边的类型必须相同,导致了下面的代码会报错:
|
|
|
|
模式匹配要求两边的类型必须相同,否则就会导致下面的报错:
|
|
|
|
```rust
|
|
|
|
```rust
|
|
|
|
let (x, y) = (1, 2, 3);
|
|
|
|
let (x, y) = (1, 2, 3);
|
|
|
|
```
|
|
|
|
```
|
|
|
|
因为对于元组来说,元素个数也是类型的一部分!
|
|
|
|
对于元组来说,元素个数也是类型的一部分!
|
|
|
|
|
|
|
|
|
|
|
|
#### 函数参数
|
|
|
|
#### 函数参数
|
|
|
|
函数参数也是模式:
|
|
|
|
函数参数也是模式:
|
|
|
@ -119,11 +119,11 @@ fn main() {
|
|
|
|
```rust
|
|
|
|
```rust
|
|
|
|
let Some(x) = some_option_value;
|
|
|
|
let Some(x) = some_option_value;
|
|
|
|
```
|
|
|
|
```
|
|
|
|
因为右边的值可能为`None`,这种时候就不能进行匹配,也就是上面的代码遗漏了`None`的匹配。
|
|
|
|
因为右边的值可能不为`Some`,而是`None`,这种时候就不能进行匹配,也就是上面的代码遗漏了`None`的匹配。
|
|
|
|
|
|
|
|
|
|
|
|
类似`let`和`for`、`match`都必须要求完全覆盖匹配,才能通过编译。
|
|
|
|
类似`let`和`for`、`match`都必须要求完全覆盖匹配,才能通过编译。
|
|
|
|
|
|
|
|
|
|
|
|
但是对于`if let`,就可以这样使用:
|
|
|
|
但是对于`if let`,就可以这样使用:
|
|
|
|
```rust
|
|
|
|
```rust
|
|
|
|
if let Some(x) = some_option_value {
|
|
|
|
if let Some(x) = some_option_value {
|
|
|
|
println!("{}", x);
|
|
|
|
println!("{}", x);
|
|
|
|