共享借用Vec上iter()和into_iter()的区别是什么?

9
我正在阅读 Rust 101教程,作者以一个传递给函数的Vec对象为例,讲解了共享借用。下面是教程中所示范的稍微改编过的MWE。有趣的部分在于vec_min中的v.iter()。作者写道:

这次,我们明确请求向量v的迭代器。方法iter借用它处理的向量,并提供元素的共享借用。

但是如果我在一个共享的对象上使用for ... in ...结构会发生什么?根据这篇博客文章,这个隐式的for循环使用into_iter(),占用了v的所有权。但它实际上无法占用该函数中的v,因为一开始只是借用了它,对吗?

有人能向我解释一下对于一个借用对象,into_iter()iter()之间的区别吗?

enum NumberOrNothing {
    Number(i32),
    Nothing,
}
use self::NumberOrNothing::{Number,Nothing};

impl NumberOrNothing {
    fn print(self) {
        match self {
            Nothing => println!("The number is: <nothing>"),
            Number(n) => println!("The number is: {}", n),
        };
    }
}

fn vec_min(v: &Vec<i32>) -> NumberOrNothing {
    fn min_i32(a: i32, b: i32) -> i32 {
        if a < b {a} else {b}
    }

    let mut min = Nothing;
    for e in v.iter() {
    //Alternatively implicitly and with *e replaced by e:
    //for e in v {
        min = Number(match min {
            Nothing => *e,
            Number(n) => min_i32(n, *e),
        });
    }
    min
}

pub fn main() {
    let vec = vec![18,5,7,2,9,27];
    let foo = Nothing;
    let min = vec_min(&vec);
    let min = vec_min(&vec);
    min.print();
}
1个回答

12

没有区别。

它实际上不能拥有该函数中的 v,因为一开始只是借用了它。

它完全可以拥有 v,因为它是一个 &Vec。注意精确的语义-您正在拥有引用,而不是引用的项目。

如果您查看 IntoIterator 的实现者,您可以找到:

impl<'a, T> IntoIterator for &'a Vec<T>

以下是相关源代码:

impl<'a, T, A: Allocator> IntoIterator for &'a Vec<T, A> {
    type Item = &'a T;
    type IntoIter = slice::Iter<'a, T>;

    fn into_iter(self) -> slice::Iter<'a, T> {
        self.iter()
    }
}

惊喜——它调用了iter

对于&mut vecvec.iter_mut()同样适用相同的逻辑。


4
好的,非常感谢!我之前还对into_iter()既可以在&Vec上工作也可以在Vec上工作感到困惑,但是你参考的来源解释了这一点:Vec<T>&'a Vec<T>&'a mut Vec<T>都有实现者。非常棒的内容! :) - mSSM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接