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);
}
相关推荐
本地化文档1 小时前
rust-style-guide-l10n
rust·github·gitcode
qq_525513752 小时前
第七章 指令微调学习(三)为指令数据集创建数据加载器;加载预训练的大语言模型
人工智能·学习·语言模型
阿阳微客2 小时前
网易Buff游戏搬砖,长期可做!
笔记·学习·游戏
Upsy-Daisy2 小时前
AI Agent 项目学习笔记(一):项目总体介绍与智能体链路概览
人工智能·笔记·学习
wuxinyan1232 小时前
工业级大模型学习之路019:LangChain零基础入门教程(第二篇):LLM 模块与模型抽象
人工智能·python·学习·langchain
唐璜Taro2 小时前
AI Agent 智能体:从入门到实战的学习路线
学习·ai
June bug2 小时前
【AI赋能测试笔记】5基于文档用例生成系统及skills
笔记·功能测试·职场和发展·测试用例·学习方法
sakiko_2 小时前
Swift学习笔记30-数据库SQlite语句
数据库·学习·swift
nnsix2 小时前
设计模式 - 原型模式 笔记
笔记·设计模式·原型模式