Difference between iter() and into_iter() on a shared, borrowed Vec?

依然范特西╮ 提交于 2020-08-19 11:41:45

问题


I am reading the Rust 101 tutorial, where the author talks about shared borrowing with the example of a Vec object passed to a function. Below is a slightly adapted MWE of what the the tutorial is teaching. The interesting part is v.iter() in vec_min. The author writes:

This time, we explicitly request an iterator for the vector v. The method iter borrows the vector it works on, and provides shared borrows of the elements.

But what happens if I use a for ... in ... construction on an object which is shared? According to this blog post, this implicit for loop uses into_iter(), taking ownership of v. But it cannot really take ownership of the v in that function, since it has only borrowed it to begin with, right?

Can somebody explain the difference between into_iter() and iter() applied to a borrowed object to me?

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:


But it cannot really take ownership of the v in that function, since it has only borrowed it to begin with

It absolutely can take ownership of v, because that's a &Vec. Note the precise semantics here - you are taking ownership of the reference, not of the referred-to item.

If you check out the implementors of IntoIterator, you can find:

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

And the source for that:

impl<'a, T> IntoIterator for &'a Vec<T> {
    fn into_iter(self) -> slice::Iter<'a, T> {
        self.iter()
    }
}

Surprise — it calls iter! So the answer to your question is: there isn't a difference.



来源:https://stackoverflow.com/questions/32234954/difference-between-iter-and-into-iter-on-a-shared-borrowed-vec

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!