问题
I'm trying to sort a Vec
of enums. Please ignore the sorting mechanism itself, this is just a stripped-down example.
use std::cmp::Ordering;
enum MyEnum {
Option1,
Option2,
}
fn main() {
let mut my_list: Vec<MyEnum> = vec![MyEnum::Option1, MyEnum::Option2, MyEnum::Option1];
// (1) - doesn't work
my_list.sort_unstable_by(|a, b| match (*a, *b) {
(MyEnum::Option1, MyEnum::Option1) => Ordering::Equal,
(MyEnum::Option1, MyEnum::Option2) => Ordering::Less,
_ => Ordering::Greater
});
}
I get the following error:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:12:44
|
12 | my_list.sort_unstable_by(|a, b| match (*a, *b) {
| ^^ cannot move out of borrowed content
The following two variants work:
// (2)
my_list.sort_unstable_by(|a, _b| match *a {
MyEnum::Option1 => Ordering::Less,
MyEnum::Option2 => Ordering::Greater
});
// (3)
my_list.sort_unstable_by(|a, b| match (a, b) {
(&MyEnum::Option1, &MyEnum::Option1) => Ordering::Equal,
(&MyEnum::Option1, &MyEnum::Option2) => Ordering::Less,
_ => Ordering::Greater
});
When I want to match a plain reference, I can dereference it (variant 2); why doesn't this work inside the tuple in variant 1?
I understand why 3 works, but struggle with understanding where exactly a move happens in 1 and how to do it differently.
回答1:
where exactly a move happens
A move happens where the compiler is pointing — *a
. You are moving the contents of a
into a brand-new tuple. You can't do that, so the compiler gives an error.
The ability to "dereference" the matched variable without really dereferencing it is some syntactic goodness provided by the compiler, but it's very limited. It doesn't "see into" the expression, it only looks at some select syntax constructions and knows to ignore them.
It's possible that the compiler could be enhanced to see these cases, but presumably the cost/benefit tradeoff isn't favorable at this point in time.
See also:
- Is there any difference between matching on a reference to a pattern or a dereferenced value?
- How can I use match on a pair of borrowed values without copying them?
- Matching on a reference to an enum
来源:https://stackoverflow.com/questions/48044295/why-does-matching-on-a-tuple-of-dereferenced-references-not-work-while-dereferen