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);
}
相关推荐
Cloud_Shy6189 小时前
解读《Effective Python 3rd Edition》:从练气到老魔(第五章 Item 30 - 32)
开发语言·人工智能·笔记·python·学习方法
lizhihai_999 小时前
股市学习心得-AI 产业链核心标的梳理清单
大数据·服务器·人工智能·科技·学习
问心无愧05139 小时前
ctf show web入门110
前端·笔记
吃好睡好便好9 小时前
说说科学爬山
学习·生活
道一239 小时前
Windows系统查看端口占用进程的3种实用方法
windows·笔记
lunzi_082610 小时前
【学习笔记】《Python编程 从入门到实践》第8章:函数定义、参数传递与模块导入
笔记·python·学习
零陵上将军_xdr11 小时前
后端转全栈学习-Day5-JavaScript 基础-3
开发语言·javascript·学习
05大叔12 小时前
对话系统学习,问答型数据库,闲聊型对话数据库
学习
nashane12 小时前
HarmonyOS 6商城开发学习:抢票倒计时与系统日历提醒——票务类场景的完整落地思路
学习·华为·harmonyos
Yuyubow12 小时前
gpui step by step 5. FocusHandle 焦点处理与键盘点击事件
rust