当前位置:  开发笔记 > 编程语言 > 正文

iter和into_iter有什么区别?

如何解决《iter和into_iter有什么区别?》经验,为你挑选了3个好方法。

我正在做Rust示例教程,其中包含以下代码片段:

// Vec example
let vec1 = vec![1, 2, 3];
let vec2 = vec![4, 5, 6];

// `iter()` for vecs yields `&i32`. Destructure to `i32`.
println!("2 in vec1: {}", vec1.iter()     .any(|&x| x == 2));
// `into_iter()` for vecs yields `i32`. No destructuring required.
println!("2 in vec2: {}", vec2.into_iter().any(| x| x == 2));

// Array example
let array1 = [1, 2, 3];
let array2 = [4, 5, 6];

// `iter()` for arrays yields `&i32`.
println!("2 in array1: {}", array1.iter()     .any(|&x| x == 2));
// `into_iter()` for arrays unusually yields `&i32`.
println!("2 in array2: {}", array2.into_iter().any(|&x| x == 2));

我很困惑 - 对于Veciteryield引用返回的迭代器和从into_iteryield值返回的迭代器,但是对于数组,这些迭代器是相同的吗?

这两种方法的用例/ API是什么?



1> Matthieu M...:

第一个问题是:"什么是into_iter?"

into_iter来自这个IntoIterator特质:

pub trait IntoIterator 
where
    ::Item == Self::Item, 
{
    type Item;
    type IntoIter: Iterator;
    fn into_iter(self) -> Self::IntoIter;
}

当您想要指定如何将特定类型转换为迭代器时,可以实现此特征.最值得注意的是,如果一个类型实现IntoIterator它可以在for循环中使用.

例如,Vec实现IntoIterator......三次!

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

每个变体略有不同.

这个消耗它Vec和它的迭代器产生(T直接):

impl IntoIterator for Vec {
    type Item = T;
    type IntoIter = IntoIter;

    fn into_iter(mut self) -> IntoIter { /* ... */ }
}

另外两个通过引用获取向量(不要被签名所欺骗,into_iter(self)因为self在两种情况下都是引用)并且它们的迭代器将生成对内部元素的引用Vec.

这个产生不可变引用:

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

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

虽然这个产生了可变引用:

impl<'a, T> IntoIterator for &'a mut Vec {
    type Item = &'a mut T;
    type IntoIter = slice::IterMut<'a, T>;

    fn into_iter(self) -> slice::IterMut<'a, T> { /* ... */ }
}

所以:

iter和之间有什么区别into_iter

into_iter是获取迭代器的通用方法,无论此迭代器是否产生值,不可变引用或可变引用是否依赖于上下文,有时可能会令人惊讶.

iter并且iter_mut是临时方法.这适用于依赖于上下文的位,并且按照惯例,让您获得将产生引用的迭代器.

Rust by Example帖子的作者说明了来自依赖于into_iter被调用的上下文(即类型)的惊喜,并且还通过使用以下事实来复合问题:

    IntoIterator没有实现[T; N],仅用于&[T; N]&mut [T; N]

    如果没有为某个值实现某个方法,则会自动搜索该值的引用

这是非常令人惊讶的,into_iter因为所有类型(除了[T; N])都为所有3种变体(值和引用)实现它.数组不可能实现一个产生值的迭代器,因为它不能"缩小"以放弃它的项目.

至于为什么数组实现IntoIterator(以这种令人惊讶的方式):它可以在循环中迭代对它们的引用for.


我发现此博文有用:http://hermanradtke.com/2015/06/22/effectively-using-iterators-in-rust.html

2> 小智..:

我(一个Rust新手)从Google来到这里,寻求一个简单的答案,而其他答案没有提供。这是简单的答案:

iter() 通过引用遍历项目

into_iter() 遍历项目,将其移至新范围

iter_mut() 遍历项目,为每个项目提供可变的引用

因此for x in my_vec { ... }本质上等同于my_vec.into_iter().for_each(|x| ... )-将这两个move元素都my_vec纳入...范围。

如果您只需要“查看”数据,请使用iter;如果您需要对其进行编辑/突变,请使用iter_mut;如果需要给它一个新的所有者,请使用into_iter

这很有帮助:http : //hermanradtke.com/2015/06/22/effectively-using-iterators-in-rust.html

将其设置为社区Wiki,以便我犯任何错误时希望Rust专业人员可以编辑此答案。



3> viraptor..:

.into_iter()没有为数组本身实现,但只是&[].相比:

impl<'a, T> IntoIterator for &'a [T]
    type Item = &'a T

impl IntoIterator for Vec
    type Item = T

由于IntoIterator仅定义了&[T],因此切片本身的删除方式与Vec使用值时不同.(值无法移出)

现在,为什么这是一个不同的问题,我想学习自己.推测:数组本身就是数据,切片只是一个视图.在实践中,您不能将数组作为值移动到另一个函数中,只需传递它的视图,因此您也不能在那里使用它.

推荐阅读
可爱的天使keven_464
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有