如果我尝试迭代两次切片,它可以正常工作:
let a = &[1, 2, 3];
for i in a {
println!("{}", i);
}
for i in a { // works fine
println!("{}", i);
}
Run Code Online (Sandbox Code Playgroud)
如果我尝试迭代向量两次,它会失败:
let a = vec![1, 2, 3];
for i in a {
println!("{}", i);
}
for i in a {
println!("{}", i);
}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
我看到IntoIterator特征是self按值获取的,所以我觉得第二个例子失败了.为什么第一个例子成功了?
DK.*_*DK. 21
就像你说的那样,for通过接受你要求它迭代的东西,然后传递它IntoIterator::into_iter来产生实际的迭代器值.正如你所说,按价值into_iter取得主题.
因此,当您尝试Vector直接迭代a时,这意味着您将整个向量按值传递到其IntoIterator实现中,从而消耗了流程中的向量.这就是为什么你不能直接迭代一个向量两次:第一次使用它迭代它,之后它就不再存在了.
但是,切片是不同的:切片是指向其数据的不可变的,借用的指针; 不可变的,借来的指针可以自由复制.这意味着IntoIteratorfor immutable slice只是借用数据而不消耗它(不是它可以).或者,以另一种方式来看,它的IntoIterator实现只是取一个切片的副本,而你不能复制一个Vec.
应该注意的是,您可以通过遍历借位来迭代a Vec 而不消耗它.如果您检查文档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.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3160 次 |
| 最近记录: |