这将失败:
fn ppv(arr: &mut Vec<i32>) {
if arr.len() <= 0 {
return;
}
let mut pp: i32 = 0;
for &mut val in arr {
if val == pp {
pp = val;
}
}
println!("arr is {:?}", &arr);
}但这会过去的:
fn ppv(arr: &mut Vec<i32>) {
if arr.len() <= 0{
return;
}
let mut pp: i32 = 0;
for &mut val in arr.into_iter() {
if val == pp {
pp = val;
}
}
println!("arr is {:?}", &arr);
}当我编译第一个程序时,它失败了:
error[E0382]: borrow of moved value: `arr`
--> src/main.rs:12:29
|
2 | fn ppv(arr: &mut Vec<i32>) {
| --- move occurs because `arr` has type `&mut Vec<i32>`, which does not implement the `Copy` trait
...
7 | for &mut val in arr {
| --- `arr` moved due to this implicit call to `.into_iter()`
...
12 | println!("arr is {:?}", &arr);
| ^^^^ value borrowed here after move
|为什么会这样呢?它对它的解释是否不同?第一种情况将隐式调用into_iter(),它失败了,当我调用into_iter()时,它通过了。发生了什么?
发布于 2021-08-26 10:03:25
我认为区别在于在后一种情况下执行的再借,而不是前者。
可变引用通常不是Copy。这是设计上的,因为复制可变引用将允许可变的混叠。但问题是这是如何运作的:
fn foo(v: &mut Vec<i32>) {
v.push(1); // equivalent to Vec::push(v, 1)
v.push(2); // equivalent to Vec::push(v, 2)
}如果对push()的第一次调用接收到v (而不是Copy ),那么对push()的第二次调用应该无法用“使用移动值”进行编译。然而,它也会编译,就像desugared版本一样。
它编译的原因是编译器自动执行重新借用,将v替换为&mut *v。换句话说。此转换是对接收方(self)和函数参数进行的:
// v is &mut Vec<i32>
v.push(1); // treated as (&mut *v).push(1)
Vec::push(v, 2); // treated as Vec::push(&mut *v, 2)重用表单的编译是因为允许它基于现有的可变引用(例如,通过&mut r.some_field,其中r是&mut SomeStruct)创建临时可变引用,只要临时引用比原始引用更短,并且在临时引用处于活动状态时不使用原始引用。
通常情况下,只有在很少情况下,当失败时才会注意到重新借款。这个答案用serde描述了这种情况,在这种情况下,由于使用泛型而导致重新借款失败。
为了回到原来的例子,您的for循环是另一个无法进行重借的例子。给定一个可变的引用arr,for &mut val in arr和for &mut val in arr.into_iter()之间的区别是,对into_iter()的显式调用被视为(&mut *arr).into_iter(),从而允许在循环之后继续使用arr。裸for不这样做,arr对象也丢失了。
https://stackoverflow.com/questions/68936034
复制相似问题