rust语言学习笔记Trait(七) IntoIterator(由集合创建迭代器)

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 vecvec.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);
}
相关推荐
知产xiao_xin6 小时前
知识产权入门 —— 相关权(邻接权)
经验分享·笔记·知识产权
自小吃多7 小时前
DXF文件导入与PCB板框定义笔记
笔记·嵌入式硬件
是隼人8 小时前
buuctf-pwn xdctf2015_pwn200题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门
q平面人8 小时前
【总工笔记】mindoc平板、桌面端笔记软件,发布到mindoc服务端
rust·tauri·华为平板·mindoc·总工笔记
jike_20268 小时前
iPhone采访录音同时拍现场照片的APP:图片音频同步记录实测
笔记·智能手机·音视频·语音识别
大衛說8 小时前
《Python 从入门到精通》系列总览与学习路线
开发语言·python·学习
MC皮蛋侠客9 小时前
Tauri 2.x 系列(九):安全模型——Capabilities、Permissions、Scope 与 CSP
rust·tauri
吃好睡好便好9 小时前
查找函数的使用
学习·算法·matlab·生活·查找函数
学运维的Kysan10 小时前
暑假运维学习打卡第二十九天8.29
学习
————A10 小时前
Agent 接收用户上传文件
人工智能·笔记·python·状态模式