gpt4 book ai didi

rust - 为什么我可以遍历一个切片两次,而不是一个向量?

转载 作者:行者123 更新时间:2023-11-29 08:32:09 28 4
gpt4 key购买 nike

如果我尝试遍历一个切片两次,it works fine :

let a = &[1, 2, 3];
for i in a {
println!("{}", i);
}
for i in a { // works fine
println!("{}", i);
}

如果我尝试对一个向量进行两次迭代,it fails :

let a = vec![1, 2, 3];
for i in a {
println!("{}", i);
}
for i in a {
println!("{}", i);
}
error[E0382]: use of moved value: `a`
--> src/main.rs:6:14
|
3 | for i in a {
| - value moved here
...
6 | for i in a {
| ^ value used here after move
|
= note: move occurs because `a` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait

我看到 IntoIterator trait 按值获取 self,因此第二个示例失败对我来说很有意义。为什么第一个例子会成功?

最佳答案

就像你说的,for通过获取你要求它迭代的东西,并将它传递给 IntoIterator::into_iter 来工作生成实际的 迭代器值。也如你所说,into_iter 按值接受主题。

因此,当您尝试遍历 Vector 时直接地,这意味着你将整个向量按值传递给它的IntoIterator实现,从而在过程中消耗向量。这就是为什么您不能直接遍历向量两次:第一次遍历它会消耗它,之后它不再存在。

然而,切片不同:切片是一个不可变的、借用的指向其数据的指针;不可变的,借用的指针可以自由复制。这意味着 IntoIterator对于不可变切片,它只是借用数据而不使用它(不是它可以)。或者,换个角度看,它是 IntoIterator实现只是获取切片的副本,而您不能复制 Vec。 .

需要注意的是,您可以遍历 Vec 无需通过遍历借用来消耗它。如果您检查 documentation for Vec ,您会注意到它列出了 IntoIterator 的实现对于 Vec<T> , &Vec<T>&mut Vec<T> .

let mut a: Vec<i32> = vec![1, 2, 3];

for i in &a { // iterate immutably
let i: &i32 = i; // elements are immutable pointers
println!("{}", i);
}

for i in &mut a { // iterate mutably
let i: &mut i32 = i;// elements are mutable pointers
*i *= 2;
}

for i in a { // iterate by-value
let i: i32 = i; // elements are values
println!("{}", i);
}

// `a` no longer exists; it was consumed by the previous loop.

关于rust - 为什么我可以遍历一个切片两次,而不是一个向量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54001208/

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