Reputation: 7867
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),
// ...
}
Upvotes: 8
Views: 4020
Reputation: 430634
Editor's note — this answer was posted when the question was titled "Was Rust's ref keyword avoidable?". The OP has since changed the title, making the phrasing of the answer less sensible.
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:
Upvotes: 12