如何避免循环内"move occurs because `v` has type `Vec<char>`, which does not implement the `Copy` trai



似乎这里正在发生禁止借用,但我没有看到绕过它做我需要做的事情的方法。看起来问题发生在设置循环内的mut值之后,然后尝试将其保存到另一个Vec中。有没有一种干净的方法来解决这个问题或者一种方法来显示这个移动到编译器,这样我就不会得到错误?我将在代码片段下面包含错误:

let mut result: Vec<String> = vec![];
let mut v = vec![];
for idx in 0..board.spaces.len() {
let c: char = match board.count_at(idx as u32) {
0 => ' ',
1 => '1',
2 => '2',
3 => '3',
4 => '4',
5 => '5',
6 => '6',
7 => '7',
8 => '8',
_ => 'F'
};
v.push(c);
if idx as u32 + 1 % board.width == 0 {
result.push(v.into_iter().collect());
v.clear();
}
}

错误:

error[E0382]: borrow of moved value: `v`
--> src/lib.rs:41:9
|
26  |     let mut v = vec![];
|         ----- move occurs because `v` has type `Vec<char>`, which does not implement the `Copy` trait
...
41  |         v.push(c);
|         ^^^^^^^^^ value borrowed here after move
...
44  |             result.push(v.into_iter().collect());
|                           ----------- `v` moved due to this method call, in previous iteration of loop
|
note: this function takes ownership of the receiver `self`, which moves `v`

你的代码不工作的原因是.into_iter()消耗了Vec,它不能再在程序的后面使用。你可以这样做:

result.push(v.iter().clone().collect());

,但我会将临时数据保存在String中,并将其克隆推入Vec:

let mut result: Vec<String> = vec![];
let mut s = String::new();
for idx in 0..board.spaces.len() {
let c: char = match board.count_at(idx as u32) {
0 => ' ',
1 => '1',
2 => '2',
3 => '3',
4 => '4',
5 => '5',
6 => '6',
7 => '7',
8 => '8',
_ => 'F'
};
s.push(c);
if idx as u32 + 1 % board.width == 0 {
result.push(s.clone());
s.clear();
}
}

您可以使用Vec::append()作为" empty myself ",将所有元素传递给一个新的vector ";

let mut result: Vec<String> = vec![];
let mut v = vec![];
for idx in 0..board.spaces.len() {
let c: char = match board.count_at(idx as u32) {
0 => ' ',
1 => '1',
2 => '2',
3 => '3',
4 => '4',
5 => '5',
6 => '6',
7 => '7',
8 => '8',
_ => 'F'
};
v.push(c);
if idx as u32 + 1 % board.width == 0 {
let mut s = Vec::new();
s.append(&mut v); // Pass all elements from `v` to `s`.
result.push(s.into_iter().collect());
}
}

您也可以直接使用String并使用push()推送字符,但由于String不包含append方法,您可以使用std::mem::take():

let mut result: Vec<String> = vec![];
let mut v = String::new();
for idx in 0..board.spaces.len() {
let c: char = match board.count_at(idx as u32) {
0 => ' ',
1 => '1',
2 => '2',
3 => '3',
4 => '4',
5 => '5',
6 => '6',
7 => '7',
8 => '8',
_ => 'F'
};
v.push(c);
if idx as u32 + 1 % board.width == 0 {
result.push(std::mem::take(&mut v));
}
}

最新更新