3 回答
TA贡献1887条经验 获得超5个赞
第一个问题是:“什么是into_iter?”
into_iter来自IntoIterator特征:
pub trait IntoIterator
where
<Self::IntoIter as Iterator>::Item == Self::Item,
{
type Item;
type IntoIter: Iterator;
fn into_iter(self) -> Self::IntoIter;
}
当您要指定如何将特定类型转换为迭代器时,可以实现此特征。最值得注意的是,如果类型实现IntoIterator,则可以在for循环中使用它。
例如,Vec实施IntoIterator……三次!
impl<T> IntoIterator for Vec<T>
impl<'a, T> IntoIterator for &'a Vec<T>
impl<'a, T> IntoIterator for &'a mut Vec<T>
每个变体都略有不同。
这个消耗,Vec并且它的迭代器产生值(T直接):
impl<T> IntoIterator for Vec<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(mut self) -> IntoIter<T> { /* ... */ }
}
另外两个通过引用获取向量(在两种情况下都不要被into_iter(self)因为self是引用的签名所欺骗),并且它们的迭代器将生成对内部元素的引用Vec。
这产生了不可变的参考:
impl<'a, T> IntoIterator for &'a Vec<T> {
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<T> {
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。
TA贡献1836条经验 获得超5个赞
.into_iter()不是针对数组本身实现的,而仅针对&[]。相比:
impl<'a, T> IntoIterator for &'a [T]
type Item = &'a T
与
impl<T> IntoIterator for Vec<T>
type Item = T
由于IntoIterator仅在上定义&[T],因此切片本身无法像Vec使用值那样被丢弃。(值不能移出)
现在,为什么是这样,这是一个不同的问题,我想学习一下自己。推测:数组是数据本身,切片只是对其的视图。实际上,您不能将数组作为值移动到另一个函数中,只能传递它的视图,因此也不能在那里使用它。
- 3 回答
- 0 关注
- 1668 浏览
添加回答
举报