不匹配的 arm 是否在 Rust 的 "match" 语句中获取变量的所有者?
Does non-matching arm take the owner of a variable in a "match" statement in Rust?
我是 Rust 新手。下面是我的测试。
#[derive(Debug)]
enum Food {
Cake,
Pizza,
Salad,
}
#[derive(Debug)]
struct Bag {
food: Food
}
fn main() {
let bag = Bag { food: Food::Cake };
match bag.food {
Food::Cake => println!("I got cake"),
x => println!("I got {:?}", x)
}
println!("{:?}", bag);
}
当我 运行 它时,我得到了一个错误。
error[E0382]: borrow of moved value: `bag`
--> src\main.rs:20:22
|
17 | x => println!("I got {:?}", x)
| - value moved here
...
20 | println!("{:?}", bag);
| ^^^ value borrowed here after partial move
|
= note: move occurs because `bag.food` has type `Food`, which does not implement the `Copy` trait
很明显 bag.food
不会匹配代码中的 x
arm。为什么移动发生在那里?
x
分支在运行时不被采用并不重要,因为 match
是否取得其参数的所有权并不取决于 match
的哪个分支将实际上被采取。很像这段代码(另见 ):
let foo = "blargh".to_owned();
if false {
let _bar = foo;
}
println!("{}", foo); // error[E0382]: borrow of moved value: `foo`
foo
从未实际移动过,但这对它在 if
之后是否有效没有任何影响(它不是)。
问题中的 match
取得了 bag.food
的所有权(使 bag
无效),因为它有一个取得所有权的分支。如果您不希望该特定分支获得所有权,您可以使用 ref
模式来借用:
match bag.food {
Food::Cake => println!("I got cake"),
ref x => println!("I got {:?}", x)
}
或者,自 Rust 1.26 以来,编译器知道如何将值模式(例如 Food::Cake
)绑定到引用(例如 &bag.food
),因此您可以编写:
match &bag.food {
Food::Cake => println!("I got cake"),
x => println!("I got {:?}", x)
}
在本例中,Food::Cake
匹配值,但 x
匹配并绑定到引用,因此它与前面带有 ref
的代码片段执行相同的操作。 (您可能会看到它被称为 "default binding modes" 或 "match ergonomics"。)
我是 Rust 新手。下面是我的测试。
#[derive(Debug)]
enum Food {
Cake,
Pizza,
Salad,
}
#[derive(Debug)]
struct Bag {
food: Food
}
fn main() {
let bag = Bag { food: Food::Cake };
match bag.food {
Food::Cake => println!("I got cake"),
x => println!("I got {:?}", x)
}
println!("{:?}", bag);
}
当我 运行 它时,我得到了一个错误。
error[E0382]: borrow of moved value: `bag`
--> src\main.rs:20:22
|
17 | x => println!("I got {:?}", x)
| - value moved here
...
20 | println!("{:?}", bag);
| ^^^ value borrowed here after partial move
|
= note: move occurs because `bag.food` has type `Food`, which does not implement the `Copy` trait
很明显 bag.food
不会匹配代码中的 x
arm。为什么移动发生在那里?
x
分支在运行时不被采用并不重要,因为 match
是否取得其参数的所有权并不取决于 match
的哪个分支将实际上被采取。很像这段代码(另见
let foo = "blargh".to_owned();
if false {
let _bar = foo;
}
println!("{}", foo); // error[E0382]: borrow of moved value: `foo`
foo
从未实际移动过,但这对它在 if
之后是否有效没有任何影响(它不是)。
问题中的 match
取得了 bag.food
的所有权(使 bag
无效),因为它有一个取得所有权的分支。如果您不希望该特定分支获得所有权,您可以使用 ref
模式来借用:
match bag.food {
Food::Cake => println!("I got cake"),
ref x => println!("I got {:?}", x)
}
或者,自 Rust 1.26 以来,编译器知道如何将值模式(例如 Food::Cake
)绑定到引用(例如 &bag.food
),因此您可以编写:
match &bag.food {
Food::Cake => println!("I got cake"),
x => println!("I got {:?}", x)
}
在本例中,Food::Cake
匹配值,但 x
匹配并绑定到引用,因此它与前面带有 ref
的代码片段执行相同的操作。 (您可能会看到它被称为 "default binding modes" 或 "match ergonomics"。)