Rust by example: The ref pattern

后端 未结 2 543
终归单人心
终归单人心 2021-01-12 21:10

I have problems understanding the ref pattern in Rust. I am referring to https://rustbyexample.com/scope/borrow/ref.html

Here is the code I don\'t under

相关标签:
2条回答
  • 2021-01-12 21:30

    ref creates a pointer into the piece of memory that is being matched on, in this case, ref_to_x is pointing directly to the memory that stores point.x, it is the same as writing let ref_to_x = &point.x in this case.

    The pattern is extremely important, as it allows one to reach deep inside complicated data-structures without disturbing the ownership hierarchy. For example, if one has val: &Option<String>, writing

    match *val {
        Some(s) => println!("the string is {}", s),
        None => println!("no string"
    }
    

    is not legal, it gives an error like:

    <anon>:3:11: 3:15 error: cannot move out of borrowed content
    <anon>:3     match *val {
                       ^~~~
    <anon>:4:14: 4:15 note: attempting to move value to here
    <anon>:4         Some(s) => {}
                          ^
    <anon>:4:14: 4:15 help: to prevent the move, use `ref s` or `ref mut s` to capture value by reference
    <anon>:4         Some(s) => {}
                          ^
    

    It is not legal to take ownership (move) out of a borrowed value, because that would possibly damage the thing from which the value was borrowed (violating its invariants, causing data to disappear unexpectedly, etc.).

    So, one can instead use a reference to just point in the memory with a borrowing & reference.


    There's a slight subtlety here because (a) point isn't borrowed, so it is OK to move out of point (which consumes ownership of point too, meaning it can't be used later unless reinitialised), and (b) the type int is Copy, so doesn't move ownership when used by value. This is why using myx instead works fine. If the type of x was, say, String (which isn't Copy) and point was borrowed, then the ref will be necessary.

    0 讨论(0)
  • 2021-01-12 21:46

    A reference created with ref is exactly the same as reference taken with &.

    The difference is where they're allowed in the syntax. ref on the left side of an assignment is like adding & on the right side.

    These expressions are equivalent:

    let ref x1 = y;
    let x2 = &y;
    

    This redundancy exists because in pattern matching & is used to require that a reference exists already, rather than to make a new one:

    let foo = 1;
    match foo {
       ref x => {
           /* x == &1 */ 
           match x {
               &y => /* y == 1 */
           }
       },  
    }
    

    (discussion)

    0 讨论(0)
提交回复
热议问题