Movement in match expression and ref keyword

I am not able to understand why following code will not compile because of movement during pattern matching:

    struct Node<T> {
        data: Option<T>
    }

    impl<T> Node<T> {
        pub fn print_if_present(&self) -> () {
            match self.data {
                None => println!("Nothing present."),
                Some(v) => println!("Something is there.")
            }
        }
    }

    let n = Node::<i32>{ data: Some(99) };
    n.print_if_present();
}

The line Some(v) => println!("Something is there.") causes following compilation failure:

  --> src/main.rs:8:19
   |
8  |             match self.data {
   |                   ^^^^ cannot move out of borrowed content
9  |                 None => println!("Nothing present."),
10 |                 Some(v) => println!("Something is there.")
   |                      - hint: to prevent move, use `ref v` or `ref mut v`

Where is the movement of values happening here?

However Some(_) => println!("Something is there.") builds and runs successfully. I understand that _ is unused value and hence prevents movement.

Why ref v would solve it and why &v wouldn’t help?

See this thread:

You want to borrow (&) a value, such as &self.data (with which your code will compile), or bind the new variable v by reference (ref pattern). Using & in a pattern goes the other way around and would try to bind v by dereference, which makes no sense here (unless T were to be a reference itself)

4 Likes

I recommend match &self.data {. With this pattern it’s visually clear that you don’t move anything, and you don’t have to change other codes.

Personally I hate ref pattern. It can be read as same as & pattern, but works in strictly opposite way. I think the error message in this case should be changed to promote so-called “match ergonomics” feature.

3 Likes

Thanks! It does clarify a lot of things. Also Ref keyword versus & is a great post for starters.

Thanks :slight_smile: Will check match ergonomics. As a rust learner, I have to know these patterns even if I don’t use.

Conveniently, the master branch of the compiler has been updated so that this error now gives @Hyeonu’s suggestion, so this will be easier once that makes it to stable.

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.