What can ref do that references couldn't?

99封情书 提交于 2020-08-05 07:11:21

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!