无法分配给 `self.x` 因为它是借来的

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

我有两个功能:

// 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 创建一个新的 S 对象。这似乎可行,但如果我做错了什么并且恰好有效,请纠正我。

  2. calc 尝试修改成员 xy.

编译器报错:

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

我从哪里借来的self.x?我是 Rust 的新手,但这样的事情毫无意义。

calc return 开头的所有变量绑定共享对 self.xself.y 的引用(&u8),这意味着您可以不再改变它们。

为了在最后一次分配时不受这些借用的约束,您可以 clone() 引用以获得常规 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();

我不确定这是否能解决您的所有问题,因为您没有提供 norm_value 的签名。

至于 new 方法,您可能希望更改签名以通过值而不是通过引用获取它们:

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]);

请注意,我删除了下划线 - 您不需要在函数参数前加上它们,如果您删除它们,编译器仍然会清楚。在变量标识符前加下划线通常用于消除 #[warn(unused_variables)] 警告。