这可能是一个愚蠢的问题,但它解决了我。
我从全能的book开始学习生锈。 在迭代器章节(其中链接的那个)中,有以下示例
fn iterator_demonstration() {
let v1 = vec![1, 2, 3];
let mut v1_iter = v1.iter();
assert_eq!(v1_iter.next(), Some(&1));
assert_eq!(v1_iter.next(), Some(&2));
assert_eq!(v1_iter.next(), Some(&3));
assert_eq!(v1_iter.next(), None);
}
这本书有点茫然,但我想知道 - 为什么需要&符号?
编辑:只是为了澄清 - 我理解iter
遍历不可变引用。我只是不太了解引用数字文字(再次,菜鸟问题。)
答案 0 :(得分:4)
因为他们是指针。按照文档。
v1
是Vec<i32>
。因此T
是i32
。Vec
没有iter
方法。它 Deref
到[T]
。向下滚动。[T]
有iter
方法。它返回std::slice::Iter<T>
。v1_iter
是Iter<i32>
,因此T
为i32
。next
是Iterator
特征的一部分,因此请向下滚动并查找impl Iterator
部分。next
返回Option<&'a T>
。替换T
,这会为您提供Option<&'a i32>
。先发制人:他们为什么指点?
因为那就是你要求的。如果您希望通过迭代器移动 Vec
的内容,则需要使用Vec::into_iter
或Vec::drain
。
答案 1 :(得分:0)
函数Vec::iter()
的类型为(self :&Vec<T>) -> Q<&T>
。也就是说,它创建了某种类型Q
的迭代器,这里的迭代器并不重要,它会迭代对T
中Vec
元素的引用。它使用Vec
的不可变引用,因此它不会取消任何元素或对Vec
产生任何影响。
所有Iterator
都有一个cloned()
方法,可以将&T
引用上的迭代器转换为超过T
值的迭代器,只要T
具有Clone
特质。clone()
它将另一个迭代器包装在一些代码中,这些代码在对元素的所有引用上调用T
方法,将它们转换为新的fn iterator_demonstration() {
let v1 = vec![1, 2, 3];
let mut v1_iter = v1.iter().cloned();
assert_eq!(v1_iter.next(), Some(1));
assert_eq!(v1_iter.next(), Some(2));
assert_eq!(v1_iter.next(), Some(3));
assert_eq!(v1_iter.next(), None);
}
。
Vec
IntoIterator
还实现了Vec
,它将T
传递到T
上的迭代器中,占用Vec
中的所有Vec
并且将它们传回去。它会销毁T
并获取其所有into_iter()
值的所有权。您可以使用fn iterator_demonstration2() {
let v1 = vec![1, 2, 3];
let mut v1_iter = v1.into_iter();
assert_eq!(v1_iter.next(), Some(1));
assert_eq!(v1_iter.next(), Some(2));
assert_eq!(v1_iter.next(), Some(3));
assert_eq!(v1_iter.next(), None);
}
fn iterator_demonstration3() {
let v1 = vec![1, 2, 3];
for i in v1 {
println!("{}", i);
}
}
方法明确使用它,它也用于for循环。
_db.GetCollection<T>().FindAll().Where(q => listValues.Contains(Convert.ToInt32(q.GetProperty(idColumnName))));