如果我有一个向量:
let mut v = vec![0, 1, 2, 3, 4, 5];
我会循环遍历它:
for &item in v.iter() {}
这里的&item
是引用还是值?从&
部分来看似乎是引用,但阅读详细信息后似乎显示它是一个值?
Iterator::Item
来确定项的类型。例如,Vec::iter()
的文档告诉你返回类型是std::slice::Iter
。而Iter
的文档则列出了该类型实现的特性列表,其中包括Iterator
trait。如果你展开文档,就可以看到更多信息。type Item = &'a T
这告诉你,由Vec<T>::iter()
返回的迭代器的项类型为&T
,即您获得对向量本身的项类型的引用。
在表示法中
for &item in v.iter() {}
for item in &v {{/* 这里的&可以理解为引用,表示对v进行遍历 */}}
for
后面的部分是一个被匹配到迭代器中的模式。在第一次迭代中,&item
会与&0
进行匹配,所以item
变成了0
。你可以在任何Rust介绍中了解更多有关模式匹配的内容。
另一种遍历向量v
的方法是写成:
for item in v {}
for &item in &v {}
这里借用引用v
,作为类型&Vec<i32>
的参考,并在该引用上调用IntoIterator
方法,该方法将返回与上述相同的Iter
类型,因此它也会产生引用。
let
语句、match
语句还是传递函数参数时,只要给一个变量命名,都遵循同样的规则:如果该值的类型实现了Copy
,则该值会被复制,否则它将被移动。在这种情况下,该值位于引用后面,因此它不能被移动,而且这仅适用于实现了Copy
的类型。这些类型不一定是“原始”类型,因为您也可以为自定义类型实现Copy
。 - Sven Marnach