Rust 中IntoIterator和Iterator是2个密切相关但用途不同的trait,顾名思义IntoIterator用于从某个类型创建Iterator.Trait作用用法示例Iterator定义了迭代器的行为 ,如何获取下一个元素.next()vec.iter()IntoIterator从一个类型获取迭代器,定义了可以变成迭代器的类型.into_iter()for x in vecIntoIterator 定义 pub trait IntoIterator { type Item; type IntoIter: Iterator<Item = Self::Item>; fn into_iter IntoIterator trait. impl<I: Iterator> IntoIterator for I { type Item = I::Item; type IntoIter = I; #[inline]
IntoIterator 看似简单,但蕴含的设计哲学相当深刻。让我们一起来剖析它吧! 核心概念:所有权的艺术 IntoIterator 是 Rust 标准库中最优雅的 trait 之一。 Rust 编译器会自动调用 collection.into_iter(),这正是 IntoIterator trait 的核心方法。但这里有个关键点:into_iter 消费所有权。 三重境界:&T、&mut T、T IntoIterator 的真正威力体现在它支持三种不同的迭代方式。一个集合可以通过不同的借用级别产生不同行为的迭代器。 关键建议三:在编写通用代码时,利用 IntoIterator 的 trait bound 可以让你的函数同时接受容器和迭代器。这是一种强大但容易被忽视的模式。 } } 深层思考:编译器的智能优化 IntoIterator 之所以能在 for 循环中工作,是因为编译器对它有特殊的理解。
std::iter::IntoIterator 和 std::iter::Iterator IntoIterator pub trait IntoIterator { type Item; impl<'a, T, const N: usize> IntoIterator for &'a [T; N] where [T; N]: LengthAtMost32, { type 上面数组引用的实现IntoIterator中有一个trait bound,LengthAtMost32:从名称上可以看出是长度最大为32。 LengthAtMost32是利用array_impl! > <&'a [T] as std::iter::IntoIterator> <&'a mut [T; _] as std::iter::IntoIterator > <&'a mut [T] as std::iter::IntoIterator> = note: required by `std::iter::IntoIterator
std::iter::IntoIterator 和 std::iter::Iterator IntoIterator pub trait IntoIterator { type Item; impl<'a, T, const N: usize> IntoIterator for &'a [T; N] where [T; N]: LengthAtMost32, { type 上面数组引用的实现IntoIterator中有一个trait bound,LengthAtMost32:从名称上可以看出是长度最大为32。 LengthAtMost32是利用array_impl! > <&'a [T] as std::iter::IntoIterator> <&'a mut [T; _] as std::iter::IntoIterator > <&'a mut [T] as std::iter::IntoIterator> = note: required by `std::iter::IntoIterator
> &Inner { /* ref-to-ref conversion code */ } // No having to remember the associated types on IntoIterator #[zoet(IntoIterator)] pub fn iter(&self) -> Iter { /* ... */ } #[zoet(IntoIterator)] pub fn iter_mut(&mut self) -> IterMut { /* ... */ } #[zoet(IntoIterator)] fn into_iter(mut self)
IntoIterator 特征 由于 Vec 动态数组实现了 IntoIterator 特征,因此可以通过 into_iter 将其转换为迭代器,那如果本身就是一个迭代器,该怎么办? 实际上,迭代器自身也实现了 IntoIterator,标准库早就帮我们考虑好了: impl<I: Iterator> IntoIterator for I { type Item = I::Item 中实现了into_iter方法,并且该方法返回IntoIterator对象本身。 (大概率,传统习惯上是这样) IntoIterator和Iterator rust和python类似,区分了可迭代对象和迭代器对象。 而 IntoIterator 强调的是某一个类型如果实现了该特征,它可以通过 into_iter,iter 等方法变成一个迭代器。称为可迭代对象。
www.reddit.com/r/rust/comments/mz44xi/simdutf_v011_a_small_step_for_semver_one_giant/ Rust 1.53,为数组类型添加IntoIterator Mara Bos 最近通过了一项PR,在Rust 1.53中为数组类型添加IntoIterator实现。 在这个更新之前,只有数组的引用实现了IntoIterator,这意味着无法直接对数组类型进行迭代。 // Error, but works in 1.53 !
fn sum_from_iter_box<'a, I, T>(it: I) where I: IntoIterator<Item = &'a Box<T>>, // <-- Box<T> Sized, { ... } fn sum_from_iter_ref<'a, I, T>(it: I) where I: IntoIterator<Item = &'a &'a T>, use std::ops::Deref; fn sum_from_iter<'a, I, T, U>(it: I) where I: IntoIterator<Item = &'a T>,
pub fn run<I, T, E>(args: I, exit: E, version: cli::VersionInfo) -> error::Result<()> where I: IntoIterator RP> where CC: StructOpt + Clone + GetLogFilter, RP: StructOpt + Clone + AugmentClap, I: IntoIterator , <I as IntoIterator>::Item: Into<std::ffi::OsString> + Clone, { ...
(三)IntoIterator 对于一般的迭代形式: for x in data {} Rust期望data是一个实现了Iterator的对象。 否则,会尝试使用IntoIterator将data转换成`Iterator`对象。 所以对于data: Vec<i32>来说,实际展开成了如下代码: for x in IntoIterator::into_iter(data) { } 这里for ... in语句使用IntoIterator 因此,凡是实现了IntoIterator的类型均可以使用for ... in语句进行迭代。 以std::vec::Vec为例,分别为Vec<T>、& Vec<T>和&mut Vec<T>实现了IntoIterator,并分别代理到into_iter()、iter() 和 iter_mut(),
数组迭代器IntoIterator 在Rust 1.53.0之前,「IntoIterator」只能用于数组的引用。 这仅适用于「.into_iter()」调用语法, 而不会影响任何其他语法,例如「for e in [1, 2, 3]」,「iter.zip([1, 2, 3])」或「IntoIterator::into_iter
Rust 团队2021-06-17宣布 Rust 的新版本 1.53.0发布,获取 Rust 1.53.0: $ rustup update stable 主要更新: 其中此版本完成了IntoIterator
("{}", a.y); c(); 数组迭代器 IntoIterator: array.into_iter() 现在是按项值遍历,替代了原来的按引用遍历。
不过,事实上,你可能也并不想接受一个宽泛的 Iterator:而是使用 IntoIterator 。这样你就可以得到一个通过调用 .into_iter() 就能轻松转换为迭代器的类型。 判断哪些类型实现了 IntoIterator 也很简单——就如文档中所说的: 实现 IntoIterator 的好处之一就是你的类型将适用于 Rust 的 for 循环。 如果你正在为一个类型实现一个可以将它的数据作为 Iterator 返回的方法,你也应该考虑为这个类型实现IntoIterator。(仅有一种迭代数据的主要方式时,才建议这么做。
数组(Array)支持 IntoIterator 在Rust 1.53之前,只有对数组的引用才实现 IntoIterator。 多次建议“仅在 Rust 2021 中为数组实现IntoIterator”。但是,这根本不可能。您不能在一个版次中存在trait实现,而在另一个版次中则不能存在,因为版次可以混合使用。
total: u32, } struct ReverseDependencies { crate_id: String, dependencies: <Vec<Dependency> as IntoIterator
写一个 Config,用 Default + FromStr 支持环境变量或文件读取; 自定义 LogLevel,实现 Display + FromStr + Ord 并写排序演示; 为 Bag 实现 IntoIterator
使用方法 等价使用方式 所有权 for item in collection for item in IntoIterator::into_iter(collection) 转移所有权 for item
} while let Some(x) = it.next() { f(x); } loop { next_event(); } break continue return 0 std::iter::IntoIterator 各种范围都可以与 for 循环一起使用,因为 Range 是一种可迭代类型,它实现了 std::iter::IntoIterator 特型(参见第 15 章)。
&BlockId<B::Block>, xts: T) -> Result<Vec<Result<ExHash, B::Error>>, B::Error> where T: IntoIterator