问题
What can ref do that references couldn't? Could
match value.try_thing() {
&Some(ref e) => do_stuff(e),
// ...
}
not be equally expressed by
match value.try_thing() {
&Some(e) => do_stuff(&e),
// ...
}
回答1:
No, it is not avoidable with your proposed syntax. Your syntax does not allow for taking a reference when otherwise a move would be permissable. In this example, inner is a copy of the integer from val and changing it has no effect on val:
fn main() {
let mut val = Some(42);
if let &mut Some(mut inner) = &mut val {
inner += 1;
}
println!("{:?}", val); // Some(42)
}
The ref keyword is needed to force taking a reference:
fn main() {
let mut val = Some(42);
if let &mut Some(ref mut inner) = &mut val {
*inner += 1;
}
println!("{:?}", val); // Some(43)
}
Match ergonomics allows writing this in a simpler manner:
fn main() {
let mut val = Some(42);
if let Some(inner) = &mut val {
*inner += 1;
}
println!("{:?}", val);
}
However, if we started with only this syntax, then we'd probably have the opposite problem and keyword, one to force a move instead; perhaps Some(move inner). In that alternate universe, there'd be a question asking if the move keyword was avoidable.
See also:
- How can the ref keyword be avoided when pattern matching in a function taking &self or &mut self?
- How does Rust pattern matching determine if the bound variable will be a reference or a value?
- Why is `ref` used instead of an asterisk in pattern matching?
- What is the syntax to match on a reference to an enum?
- Rust by example: The ref pattern
来源:https://stackoverflow.com/questions/58292554/what-can-ref-do-that-references-couldnt