ena*_*naJ 2 move pattern-matching rust
基于在模式匹配期间防止移动语义,我的理解是当我match
对结构进行操作时,如果不使用引用来进行匹配,则结构将被移动,因为它不是基本类型.为了测试这个,我实现了以下内容:
struct Point {
x: i32,
y: i32,
}
let origin = Point { x: 0, y: 0 };
match origin {
Point { x: x1, y: y1 } => println!("({},{})", x1, y1),
}
// to check if the origin has been moved, and it seems not, why ??
match origin {
Point { x: x1, y: y1 } => println!("({},{})", x1, y1),
}
Run Code Online (Sandbox Code Playgroud)
输出是(0,0) (0,0)
,这意味着原始结构仍然存在.它不应该在第一次之后被移动match
吗?
重要的不是匹配值的类型,而是每个匹配臂上绑定的每个值的类型.
在您的结构中Point
,字段x
和y
类型i32
.此类型实现Copy
,因此Rust将复制此类型的值而不是移动它们 - 这意味着原始值仍被视为有效.由于匹配臂上绑定的所有值都实现Copy
,因此不必使其无效origin
.字段访问的工作方式类似:在实现时origin.x
不会失效!origin
origin.x
Copy
现在,如果字段是一种没有实现的类型Copy
(例如String
),那么这是一个不同的故事.Rust被迫String
从场中移动到匹配臂中的绑定.结果,字段origin
无效.由于我们不能将值与无效字段一起使用,因此整个结构也会失效.
让我们稍微调整一下.请考虑以下代码:
struct Point {
x: i32,
y: String,
}
let origin = Point { x: 0, y: "zero".to_string() };
match origin {
Point { x: x1, y: _ } => println!("({},...)", x1),
}
match origin {
Point { x: x1, y: _ } => println!("({},...)", x1),
}
match origin {
Point { x: _, y: y1 } => println!("(...,{})", y1),
}
match origin {
Point { x: _, y: y1 } => println!("(...,{})", y1),
}
Run Code Online (Sandbox Code Playgroud)
在这里,我们使用占位符模式(_
)来表示我们对某个字段的值不感兴趣.我们还可以使用通配符模式(..
如在Point { x: x1, .. }
)中忽略结构模式中未命名的所有字段.在任何一种情况下,它都具有不移动被忽略的字段的效果.
在前两个匹配中,我们只绑定x
字段,它是类型i32
.因为i32
实现Copy
,origin
不会失效,即使它们都不origin
是origin.y
可复制的(origin.y
只是停留在它的位置).
在第三个匹配中,我们只绑定类型的y
字段String
.由于String
未实现Copy
,origin.y
被移入y1
,因此origin
无效.这会在第四次匹配时导致编译器错误,因为它origin
在失效后尝试使用:
error[E0382]: use of partially moved value: `origin`
--> <anon>:21:11
|
18 | Point { x: _, y: y1 } => println!("(...,{})", y1),
| -- value moved here
...
21 | match origin {
| ^^^^^^ value used here after move
|
= note: move occurs because `origin.y` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `origin.y`
--> <anon>:22:26
|
18 | Point { x: _, y: y1 } => println!("(...,{})", y1),
| -- value moved here
...
22 | Point { x: _, y: y1 } => println!("(...,{})", y1),
| ^^ value used here after move
|
= note: move occurs because `origin.y` has type `std::string::String`, which does not implement the `Copy` trait
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
218 次 |
最近记录: |