问题
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