Cannot assign to `self.x` because it is borrowed

喜夏-厌秋 提交于 2020-01-24 23:58:07

问题


I have 2 functions:

// A simple struct
struct S {
    w: u8,
    h: u8,
    x: Vec<u8>,
    y: Vec<u8>,
}

// Implementation of the struct S
impl S {
    // Seems to work
    fn new(_w: u8, _h: u8, _x: &Vec<u8>, _y: &Vec<u8>) -> S {
        S {
            w: _w,
            h: _h,
            x: _x.clone(),
            y: _y.clone(),
        }
    }

    fn calc(&mut self) {
        let mut min_x = self.x.iter().min().unwrap();
        let mut max_x = self.x.iter().max().unwrap();
        let mut min_y = self.y.iter().min().unwrap();
        let mut max_y = self.y.iter().max().unwrap();

        // Here's the line that gives the error
        self.x = self.x
            .iter()
            .map(|v| norm_value(*v, *min_x, *max_x, 0, self.w))
            .collect();
    }
}

fn norm_value<A, B, C, D, E>(_: A, _: B, _: C, _: D, _: E) -> ! { panic!() }
  1. new makes a new S object. This seems to work, but correct me if I did something horribly wrong and just happens to work.

  2. calc tries to modify the members x and y.

The compiler reports this error:

error[E0506]: cannot assign to `self.x` because it is borrowed
  --> src/main.rs:28:9
   |
22 |           let mut min_x = self.x.iter().min().unwrap();
   |                           ------ borrow of `self.x` occurs here
...
28 | /         self.x = self.x
29 | |             .iter()
30 | |             .map(|v| norm_value(*v, *min_x, *max_x, 0, self.w))
31 | |             .collect();
   | |______________________^ assignment to borrowed `self.x` occurs here

Where did I borrow self.x? I am new to Rust but things like this make no sense.


回答1:


All of the variable bindings at the beginning of calc return shared references (&u8) to self.x and self.y, which means you can no longer mutate them.

In order to not be bound by these borrows at the point of the last assignment you can clone() the references to obtain regular u8s:

let mut min_x = self.x.iter().min().unwrap().clone();
let mut max_x = self.x.iter().max().unwrap().clone();
let mut min_y = self.y.iter().min().unwrap().clone();
let mut max_y = self.y.iter().max().unwrap().clone();

I'm not sure if this solves all your issues, because you didn't provide the signature of norm_value.

As for the new method, you'll probably want to change the signature to obtain them by value instead of by reference:

fn new(w: u8, h: u8, x: Vec<u8>, y: Vec<u8>) -> S {
    S { w: w, h: h, x: x, y: y }
}

let s = S::new(10, 10, vec![1, 2, 3, 4], vec![52, 10, 23, 56]);

Note that I removed the underscores - you don't need to prepend the function arguments with them, if you remove them it will still be clear to the compiler. Prepending variable identifiers with underscores is usually used to silence the #[warn(unused_variables)] warnings.



来源:https://stackoverflow.com/questions/47133648/cannot-assign-to-self-x-because-it-is-borrowed

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