Update ch18-03-pattern-syntax.md

pull/55/head
Zheng Ping 7 years ago committed by GitHub
parent 4bb6a2dc43
commit a451a0e824

@ -282,12 +282,9 @@ fn main() {
<span class="caption">例18-18: 为了消除对未被使用变量的警告以一个下划线开始来命名变量</span> <span class="caption">例18-18: 为了消除对未被使用变量的警告以一个下划线开始来命名变量</span>
Note that there is a subtle difference between using only `_` and using a name 注意, 只使用`_`和使用一个以一个下划线起头的名字是有微妙的不同的: `_x`仍然会把值绑定到变量上但是`_`不会绑定值.
that starts with an underscore like `_x`: `_x` still binds the value to the
variable, but `_` doesn't bind at all.
Listing 18-19 shows a case where this distinction matters: `s` will still be 例18-19显示了这种区别的主要地方: `s`将仍然被转移到`_s`, 它会阻止我们继续使用`s`:
moved into `_s`, which prevents us from using `s` again:
```rust,ignore ```rust,ignore
let s = Some(String::from("Hello!")); let s = Some(String::from("Hello!"));
@ -299,11 +296,9 @@ if let Some(_s) = s {
println!("{:?}", s); println!("{:?}", s);
``` ```
<span class="caption">Listing 18-19: An unused variable starting with an <span class="caption">例18-19: 以下划线起头的未被使用的变量仍然会绑定值, 它也会拥有值的所有权</span>
underscore still binds the value, which may take ownership of the value</span>
Using underscore by itself, however, doesn't ever bind to the value. Listing 只使用下划线本身却不会绑定值. 例18-20在编译时将不会报错, 因为`s`不会被转移到`_`:
18-20 will compile without any errors since `s` does not get moved into `_`:
```rust ```rust
let s = Some(String::from("Hello!")); let s = Some(String::from("Hello!"));
@ -315,20 +310,14 @@ if let Some(_) = s {
println!("{:?}", s); println!("{:?}", s);
``` ```
<span class="caption">Listing 18-20: Using underscore does not bind the <span class="caption">例18-20: 使用下划线不会绑定值</span>
value</span>
This works just fine. Because we never bind `s` to anything, it's not moved. 上面的代码能很好的运行. 因为我们没有把`s`绑定到其它地方, 它没有被转移.
#### Ignoring Remaining Parts of a Value with `..` #### 用`..`忽略剩余的值
With values that have many parts, we can extract only a few parts and avoid 对于有多个字段的值而言, 我们可以只提取少数字段并使用`..`来代替下划线, 这就避免了用`_`把剩余的部分列出来的麻烦. `..`模式将忽略值中没有被精确匹配值中的其它部分. 在例18-21中, 我们有一个持有三维空间坐标的`Point`结构. 在`match`表达式里,
having to list underscores for each remaining part by instead using `..`. The 我们只想操作`x`坐标上的值并忽略`y`坐标和`z`坐标上的值:
`..` pattern will ignore any parts of a value that we haven't explicitly
matched in the rest of the pattern. In Listing 18-21, we have a `Point` struct
that holds a coordinate in three dimensional space. In the `match` expression,
we only want to operate on the `x` coordinate and ignore the values in the `y`
and `z` fields:
```rust ```rust
struct Point { struct Point {
@ -344,15 +333,11 @@ match origin {
} }
``` ```
<span class="caption">Listing 18-21: Ignoring all fields of a `Point` except <span class="caption">例18-21: 通过用`..`来忽略除了`x`以外的所有其它`Point`的字段</span>
for `x` by using `..`</span>
Using `..` is shorter to type than having to list out `y: _` and `z: _`. The 使用`..`比列出`y: _`和`z: _`写起来更简单. 当一个结构有很多字段但却只需要使用少量字段时`..`模式就特别有用.
`..` pattern is especially useful when working with structs that have lots of
fields in situations where only one or two fields are relevant.
`..` will expand to as many values as it needs to be. Listing 18-22 shows a use `..`将会囊括它能匹配的尽可能多的值. 例18-22显示了一个在元组中使用`..`的情况:
of `..` with a tuple:
```rust ```rust
fn main() { fn main() {
@ -366,15 +351,11 @@ fn main() {
} }
``` ```
<span class="caption">Listing 18-22: Matching only the first and last values in <span class="caption">例18-22: 用`..`匹配元组中的第一和最后一个值并忽略掉所有的其它值</span>
a tuple and ignoring all other values with `..`</span>
Here, we have the first and last value matched, with `first` and `last`. The 我们在这里用`first`和`last`来匹配了第一和最后一个值. `..`将匹配并忽略中间的所有其它值.
`..` will match and ignore all of the things in the middle.
Using `..` must be unambiguous, however. Listing 18-23 shows an example where 然而使用`..`必须清晰明了. 例18-23中的代码就不是很清晰, Rust看不出哪些值时我们想匹配的, 也看不出哪些值是我们想忽略的:
it's not clear to Rust which values we want to match and which values we want
to ignore:
```rust,ignore ```rust,ignore
fn main() { fn main() {
@ -388,10 +369,9 @@ fn main() {
} }
``` ```
<span class="caption">Listing 18-23: An attempt to use `..` in a way that is <span class="caption">例18-23: 尝试含混不清地使用`..`</span>
ambiguous</span>
If we compile this example, we get this error: 如果我们编译上面的例子, 我们会得到下面的错误:
```text ```text
error: `..` can only be used once per tuple or tuple struct pattern error: `..` can only be used once per tuple or tuple struct pattern
@ -401,20 +381,11 @@ error: `..` can only be used once per tuple or tuple struct pattern
| ^^ | ^^
``` ```
It's not possible to determine how many values in the tuple should be ignored 上面的代码中在一个值被匹配到`second`之前不可能知道元组中有多少值应该被忽略, 同样在`second`被匹配后也不知道应该有多少值被忽略. 我们可以忽略2, 把`second`绑定到4, 然后忽略8、16和32, 或者我们也可以忽略2和4, 把`second`绑定到8, 然后再忽略16和32. 对Rust而言, 变量名`second`并不意味着某个确定的值, 因为像这样在两个地方使用`..`是含混不清的, 所以我们就得到了一个编译错误.
before one value is matched with `second`, and then how many further values are
ignored after that. We could mean that we want to ignore 2, bind `second` to 4,
then ignore 8, 16, and 32, or we could mean that we want to ignore 2 and 4,
bind `second` to 8, then ignore 16 and 32, and so forth. The variable name
`second` doesn't mean anything special to Rust, so we get a compiler error
since using `..` in two places like this is ambiguous.
### `ref` and `ref mut` to Create References in Patterns ### 用`ref`和`ref mut`在模式中创建引用
Usually, when you match against a pattern, the variables that the pattern 当你匹配一个模式时, 模式匹配的变量会被绑定到一个值. 也就是说你会把值转移进`match`(或者是其它你使用了模式的地方), 这是所有权规则的作用. 例18-24提供了一个例子:
introduces are bound to a value. This means you'll end up moving the value into
the `match` (or wherever you're using the pattern) since the ownership rules
apply. Listing 18-24 shows an example:
```rust,ignore ```rust,ignore
let robot_name = Some(String::from("Bors")); let robot_name = Some(String::from("Bors"));
@ -427,8 +398,7 @@ match robot_name {
println!("robot_name is: {:?}", robot_name); println!("robot_name is: {:?}", robot_name);
``` ```
<span class="caption">Listing 18-24: Creating a variable in a match arm pattern <span class="caption">例18-24: 在一个匹配分支模式里创建的变量会拥有值的所有权</span>
takes ownership of the value</span>
This example will fail to compile since the value inside the `Some` value in This example will fail to compile since the value inside the `Some` value in
`robot_name` is moved within the `match` when `name` binds to that value. `robot_name` is moved within the `match` when `name` binds to that value.

Loading…
Cancel
Save