gpt4 book ai didi

rust - 由于对 `.into_iter()` 的这种隐式调用,对向量的可变引用被移动,但调用 `.into_iter()` 显式有效

转载 作者:行者123 更新时间:2023-12-04 11:27:50 26 4
gpt4 key购买 nike

这将失败:

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() 时,通过了。发生了什么?

最佳答案

我相信区别在于 reborrow , 在后一种情况下执行,但在前一种情况下不执行。
可变引用通常不是 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()应该无法通过“使用移动值”进行编译。然而它可以编译,脱糖版本也是如此。
它编译的原因是编译器自动进行重借,替换 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),只要临时引用的生命周期比原始引用短,并且您不要在临时引用有效时使用原始引用。
您通常会注意到只有在失败的极少数情况下才会重新借款。 This answer用 serde 描述了这种情况,其中由于使用泛型而重新借用失败。
回到最初的例子,你的 for循环是重新借用失败的另一个例子。给定一个可变引用 arrfor &mut val in arr的区别和 for &mut val in arr.into_iter()是对 into_iter() 的显式调用被视为 (&mut *arr).into_iter()从而允许继续使用 arr循环后。裸体 for不这样做,而 arr对象丢失。

关于rust - 由于对 `.into_iter()` 的这种隐式调用,对向量的可变引用被移动,但调用 `.into_iter()` 显式有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68936034/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com