Are*_*ski 8 iterator loops rust
我正在观看 Rust 讲座,发现我想到了两种迭代向量的方法。我可以迭代“向量本身”或“iter() 方法”。您能告诉我这里有什么区别吗?
fn call(from: &mut Vec<i32>, to: &mut Vec<i32>) {
for e in from.iter() {
to.push(*e);
}
for e in from {
to.push(*e);
}
}
fn printvec(from: & Vec<i32>) {
for e in from {
print!("{} ", e);
}
println!("");
}
fn main() {
let mut v1 = vec![1,2,3];
let mut v2 = vec![1,2,3];
call(&mut v1, &mut v2);
printvec(&v1);
printvec(&v2);
}
Run Code Online (Sandbox Code Playgroud)
您能告诉我这里有什么区别吗?
正如 Stargateur 所说,这里没有区别。要知道发生了什么,您只需遵循白兔特征实现:Rust 的for循环“简单地”调用IntoIterator“RHS”。现在,如果我们查看实施者列表
&Vec它本身没有记录,但查看它刚刚调用的代码self.iter(),所以在这里我们确实确认了 Stargateur 是正确的,&Vec并Vec::iter做了完全相同的事情
Vec::iter该文档有点简洁,但它链接到std::slice::Iter“不可变切片迭代器”,其本身不一定非常有帮助,但特征实现非常清晰
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T
}
Run Code Online (Sandbox Code Playgroud)
所以Vec<T>::iter-> Iter<T>-> Iterator<Item=&a>,这意味着当您使用.iter()向量(或迭代&Vec)时,您会迭代对 items 的不可变引用。而且由于iter采用&self(&Vec显然是一个引用),这也意味着迭代仅借用向量,因此一旦完成迭代,向量仍然保持不变。
&mut Vec和Vec::iter_mut尽管您没有提到这是第二个迭代器,但它与上面的迭代器类似,只是它产生了std::slice::IterMut一个
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T
}
Run Code Online (Sandbox Code Playgroud)
因此,它不是生成对项目的不可变引用,而是生成可变引用,这意味着您可以就地修改项目,例如增加它们,非常酷。
Vec本身所以我们来讨论这个,如果你扩展定义,你会看到本质上是这样的:
impl<T> IntoIterator for Vec<T> {
type Item = T
type IntoIter = IntoIter<T, A>
pub fn into_iter(self) -> IntoIter<T, A>
Run Code Online (Sandbox Code Playgroud)
创建一个消耗迭代器,即将每个值移出向量(从开始到结束)的迭代器。调用此函数后该向量将无法使用。
这是不言自明的:如果你Vec直接迭代它会消耗向量,这意味着你之后将无法使用它。
然而,作为回报,它将向量项的所有权移至迭代器中,从而提供了更大的灵活性。
| 归档时间: |
|
| 查看次数: |
4276 次 |
| 最近记录: |