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