问题
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!() }
new
makes a newS
object. This seems to work, but correct me if I did something horribly wrong and just happens to work.calc
tries to modify the membersx
andy
.
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 u8
s:
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