我正在观看一个 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);
}
最佳答案
Could you please tell me what is the difference here?
正如 Stargateur 所说,这里没有区别。要知道发生了什么,您只需要遵循 white rabbit 特征实现:Rust 的 for
循环“简单”调用 IntoIterator
在“RHS”上。现在如果我们下去 the list of implementors
我们可以看到an implementation for &Vec
它本身没有记录,但 looking at the code it just calls self.iter()
,所以这里我们确实确认了 Stargateur 是正确的,&Vec
和 Vec::iter
做同样的事情
Vec::iter
文档有点简洁,但它链接到 std::slice::Iter
这是“不可变切片迭代器”,本身不一定非常有用但特征实现非常清晰
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T
}
所以 Vec<T>::iter
-> Iter<T>
-> Iterator<Item=&a>
, 意思是当你 .iter()
一个向量(或者你迭代一个 &Vec
)你迭代对项目的不可变引用。自从iter
需要&self
(并且 &Vec
显然是一个引用)这也意味着迭代只借用向量,所以一旦你完成迭代向量仍然保持不变。
&mut Vec
和 Vec::iter_mut
虽然您没有提到它是第二个迭代器,但它与上面的迭代器相似,只是它产生 std::slice::IterMut
其中
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T
}
所以它不会产生对项目的不可变引用,而是产生可变引用,这意味着您可以就地修改项目,例如增加它们,很酷。
Vec
itself
所以我们来到这里,如果您扩展定义,您基本上会看到:
impl<T> IntoIterator for Vec<T> {
type Item = T
type IntoIter = IntoIter<T, A>
pub fn into_iter(self) -> IntoIter<T, A>
Creates a consuming iterator, that is, one that moves each value out of the vector (from start to end). The vector cannot be used after calling this.
这是不言自明的:如果您在 Vec
上进行迭代它直接消耗该向量,这意味着您将无法之后使用它。
然而,作为返回,它将向量项的所有权移动到迭代器中,这提供了更大的灵 active 。
关于loops - Rust:迭代 iter() 或向量本身,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66908520/