当前位置:  开发笔记 > 编程语言 > 正文

为什么我可以迭代两次切片,但不能迭代?

如何解决《为什么我可以迭代两次切片,但不能迭代?》经验,为你挑选了1个好方法。

如果我尝试迭代两次切片,它可以正常工作:

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

如果我尝试迭代向量两次,它会失败:

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`, which does not implement the `Copy` trait

我看到IntoIterator特征是self按值获取的,所以我觉得第二个例子失败了.为什么第一个例子成功了?



1> DK...:

就像你说的那样,for通过接受你要求它迭代的东西,然后传递它IntoIterator::into_iter来产生实际的迭代器值.正如你所说,按价值into_iter取得主题.

因此,当您尝试Vector直接迭代a时,这意味着您将整个向量按值传递到其IntoIterator实现中,从而消耗了流程中的向量.这就是为什么你不能直接迭代一个向量两次:第一次使用它迭代它,之后它就不再存在了.

但是,切片是不同的:切片是指向其数据的不可变的,借用的指针; 不可变的,借来的指针可以自由复制.这意味着IntoIteratorfor immutable slice只是借用数据而不消耗它(不是它可以).或者,以另一种方式来看,它的IntoIterator实现只是取一个切片的副本,而你不能复制一个Vec.

应该注意的是,您可以通过遍历借位来迭代a Vec 而不消耗它.如果您检查文档Vec,你会注意到它列出的实现IntoIteratorVec,&Vec&mut Vec.

let mut a: Vec = 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.


@ JackO'Connor,这基本上是正确的,除了切片中实际上没有什么神奇的实现`Copy`.切片本质上是一个不可变引用,不可变引用自然是`Copy`.
推荐阅读
云聪京初瑞子_617
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有