IntoIterator 是 Rust 迭代器的入口 trait 。它的核心职责是将一个类型(如集合、数组等)转换为一个实现了 Iterator trait 的迭代器对象。
- 任何实现了
IntoIterator的类型都可以直接在for循环中使用。
1、核心定义
rust
pub trait IntoIterator {
/// 迭代器产生的元素类型
type Item;
/// 具体的迭代器类型,必须实现 Iterator<Item = Self::Item>
type IntoIter: Iterator<Item = Self::Item>;
/// 消耗 self,创建并返回迭代器
fn into_iter(self) -> Self::IntoIter;
}
- **
Item**: 定义迭代过程中产生的每个元素的类型。 - **
IntoIter**: 定义实际执行迭代逻辑的类型。 - **
into_iter(self)**: 这是转换的核心。注意它接收self(按值传递),这意味着调用该方法通常会消耗原始数据的所有权(或者借用,取决于具体实现)。
2、三种迭代模式的所有权
(1)消费所有权 (impl IntoIterator for Vec<T>)
for item in vec 或 vec.into_iter()
rust
let v1 = vec![1, 2, 3, 4];
for i in v1 { // 消费所有权
println!("{}", i);
}
println!("{:?}", v1); // ❌已被移动
let v2 = vec![1, 2, 3, 4];
for i in v2.into_iter() { // 消费所有权
println!("{}", i);
}
println!("{:?}", v2); // ❌已被移动
(2)不可变借用 (impl<'a, T> IntoIterator for &'a Vec<T>)
for item in &vec 或 (&vec).into_iter()
rust
let v1 = vec![1, 2, 3, 4];
for i in &v1 { // 不可变借用
println!("{}", i);
}
println!("{:?}", v1); // ✅正常输出
let v2 = vec![1, 2, 3, 4];
for i in (&v2).into_iter() { // 不可变借用
println!("{}", i);
}
println!("{:?}", v2); // ✅正常输出
(3)可变借用 (impl<'a, T> IntoIterator for &'a mut Vec<T>)
for item in &mut vec 或 (&mut vec).into_iter()
rust
let mut v1 = vec![1, 2, 3, 4];
for i in &mut v1 { // 可变借用
*i += 2;
}
println!("{:?}", v1); // 已被修改
let mut v2 = vec![1, 2, 3, 4];
for i in (&mut v2).into_iter() { // 可变借用
*i -= 2;
}
println!("{:?}", v2); // 已被修改
3、函数参数约束 IntoIterator
- 函数参数必须满足:任何可迭代内容
rust
use std::fmt::{Debug, Display};
fn my_fn<I, T>(v: I)
where
I: IntoIterator<Item=T>, // 参数必须实现了 IntoIterator
T: Display, // 用于 print 输出
{
for i in v { // 遍历迭代器
print!("{} ", i);
}
println!("");
}
fn main() {
my_fn(vec![1, 2, 3]); // Vec<i32>
my_fn([1, 2, 3, 4]); // &[i32]
my_fn((5..9)); // range(i32)
my_fn(["aaa", "bbb", "ccc"]); // &[&str]
}
4、自定义类型实现 IntoIterator
rust
#[derive(Debug)]
struct MyList<T>(Vec<T>); // 自定义集合
// 实现消费所有权的 IntoIterator
impl<T> IntoIterator for MyList<T> {
type Item = T;
type IntoIter = std::vec::IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
// 实现不可变引用借用的 IntoIterator
impl<'a, T> IntoIterator for &'a MyList<T> {
type Item = &'a T;
type IntoIter = std::slice::Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.0.iter()
}
}
// 实现可变引用借用的 IntoIterator
impl<'a, T> IntoIterator for &'a mut MyList<T> {
type Item = &'a mut T;
type IntoIter = std::slice::IterMut<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.0.iter_mut()
}
}
fn main() {
// 消费所有权
let list1 = MyList(vec![1, 2, 3]);
for item in list1 {
println!("{}", item);
}
// 不可变借用
let list2 = MyList(vec![4, 5, 6]);
for item in &list2 {
println!("{}", item);
}
// 可变借用
let mut list3 = MyList(vec![4, 5, 6]);
for item in &mut list3 {
*item += 10;
}
println!("{:?}", list3);
}