Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get an enum field from a struct: cannot move out of borrowed content

I'm new to Rust and trying to wrap my head around the ownership/borrowing concept. Now I have reduced my code to this minimal code sample that gives a compile error.

pub struct Display {
    color: Color,
}

pub enum Color {
    Blue         = 0x1,
    Red          = 0x4,
}

impl Display {
    fn get_color_value(&self) -> u16 {
        self.color as u16
    }
}
src/display.rs:12:9: 12:13 error: cannot move out of borrowed content
src/display.rs:12         self.color as u16
                          ^~~~
error: aborting due to previous error
Could not compile.

I'm still in the everything is copied by value mindset, where it is perfectly legal to do self.color as that would get me a copy of Color. Apparently, I am wrong. I found some other questions about this same error on SO, but no solution to my issue.

As I understand it, the field is owned by whomever owns the Display. Since I only borrowed a reference to the Display, I don't own it. Extracting color attempts to transfer ownership of the Color to me, which is not possible since I don't own the Display. Is this correct?

How do I solve it?

like image 341
Daniel A.A. Pelsmaeker Avatar asked Mar 03 '15 23:03

Daniel A.A. Pelsmaeker


1 Answers

I'm still in the everything is copied by value mindset, where it is perfectly legal to do self.color as that would get me a copy of Color. Apparently, I am wrong. I found some other questions about this same error on SO, but no solution to my issue.

Anything that can be copied in rust must be explicitly mared with a trait Copy. Copy was implicit in the past but that was changed (rfc).

As I understand it, the field is owned by whomever owns the Display. Since I only borrowed a reference to the Display, I don't own it. Extracting color attempts to transfer ownership of the Color to me, which is not possible since I don't own the Display. Is this correct?

Yes. When you encounter this error there are three possible solutions:

  • Derive the trait Copy for the type (if appropriate)
  • Use/derive Clone (self.color.clone())
  • Return a reference

To solve this you derive Copy for Color:

#[derive(Copy, Clone)]
pub enum Color {
    Blue         = 0x1,
    Red          = 0x4,
}

This is the same as:

impl Copy for Color {}
like image 79
Arjan Avatar answered Oct 26 '22 02:10

Arjan