8

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),
    // ...
}
2
  • 1
    Complement: Rust by example: The ref pattern Commented Oct 8, 2019 at 19:15
  • 1
    I'm not sure what you mean by "avoidable". Is it necessary in this code? No. Is it necessary in any code? Kind of, yes, depending on how much you're willing to rewrite to avoid writing ref. Could the language have been designed without it? I suppose so, especially if something like default binding modes had been part of the original design, but that doesn't seem like a particularly interesting counterfactual to me... What's the point of this question? Commented Oct 8, 2019 at 19:37

1 Answer 1

12

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:

Sign up to request clarification or add additional context in comments.

4 Comments

This seems to suggest that only one of ref or move would have been strictly necessary, possibly at the cost of having the wrong default in certain scenarios.
@Ryan1729 recall that move is not a valid keyword in pattern matching today. We are already in a state where only one (ref) is necessary and we have the wrong default in certain scenarios. The OPs implicit assertion is that there's a world where no keyword is needed and the language can just Do The Right Thing.
Why not using & instead of ref here?: if let &mut Some(ref mut inner) = &mut val {
@frankelot I think the already-linked question and answer Why is ref used instead of an asterisk in pattern matching? covers that. Let me know if there's something missing.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.