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

FromIterator 定义了**"如何从一系列元素构建一个容器"**。当你调用迭代器的 .collect() 方法时,编译器底层正是通过 FromIterator trait 来决定最终生成什么类型的数据结构(如 VecHashMapString 等)

1. 核心定义

FromIterator 的定义:

rust 复制代码
pub trait FromIterator<A> {
    /// 从迭代器创建一个值
    fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self;
}
  • ‌**泛型参数 A**‌:表示迭代器中元素的类型。
  • ‌**方法 from_iter**‌:接收任何实现了 IntoIterator 的类型(即可以转为迭代器的类型),并返回 Self(实现该 trait 的具体类型)。

2、通过 Iterator::collect() 间接使用

rust 复制代码
// 这两种写法在底层是等价的
let v1: Vec<i32> = (0..5).collect();             // 推荐写法
let v2: Vec<i32> = Vec::from_iter(0..5);         // 显式调用

3. 标准库中的常见实现

Rust 标准库为许多常用类型实现了 FromIterator,使得它们可以直接从迭代器构建:

目标类型 迭代器元素类型 (Item) 说明
Vec<T> T 将元素收集到向量中
String char&str 将字符或字符串切片拼接成 String
HashMap<K, V> (K, V) 将键值对元组收集到哈希表中
HashSet<T> T 将元素收集到哈希集合中(去重)
Option<T> Option<T> 如果所有项都是 Some,则结果为 Some(Vec<T>) 等;若遇 None 则短路返回 None
Result<T, E> Result<T, E> 类似 Option,遇到第一个 Err 则短路返回错误

4、常用类型和迭代器的转换

into_iter():类型 -> 迭代器,让一个类型可以被遍历,IntoIterator Trait

  • ‌**IntoIterator**‌ 是"源":它定义了如何把一个容器打散成流。

collect():迭代器 -> 类型,让一个类型可以从迭代器构建,FromIterator Trait

  • ‌**FromIterator**‌ 是"sink"(汇聚点):它定义了如何把流重新组装成容器。
rust 复制代码
use std::collections::{HashMap, HashSet};

fn main() {
    // Range<i32> -> Vec<i32>
    let v1: Vec<i32> = (0..5).collect();
    let v1 = (0..5).collect::<Vec<i32>>();

    // [char] -> String
    let s: String = ['a', 'b'].into_iter().collect();
    let s = ['a', 'b'].into_iter().collect::<String>();

    // [(&str,i32)] -> HashMap<&str, i32>
    let m: HashMap<&str, i32> = [("a", 32), ("b", 25)].into_iter().collect();
    let m = [("a", 32), ("b", 25)].into_iter().collect::<HashMap<&str, i32>>();

    // Range<i32> -> HashSet<i32>
    let hs_i: HashSet<i32> = (0..=6).collect();
    let hs_i = (0..=6).collect::<HashSet<i32>>();

    // [char] -> HashSet<char>
    let hs_c: HashSet<char> = ['a', 'b'].into_iter().collect();

    // [&str] -> HashSet<&str>
    let hs_s: HashSet<&str> = ["aaa", "bbb"].into_iter().collect();

    // [Option<T>] -> Some(Vec<T>)
    let opt: Option<Vec<i32>> = [Some(5), Some(8), Some(11)].into_iter().collect();

    // [Option<T>] -> None,遇到None,后停止收集,短路返回 None
    let opt: Option<Vec<i32>> = [Some(5), None, Some(11)].into_iter().collect();

    // [Ok(T)] -> Ok<Vec<T>>
    let e: Result<Vec<i32>, ()> = [Ok(6), Ok(9), Ok(22)].into_iter().collect();

    // [Result(T)] -> Err,,遇到Err,后停止收集,短路返回 Err
    let e: Result<Vec<i32>, &str> = [Ok(6), Err("错误"), Ok(22)].into_iter().collect();
}

5、自定义类型实现FromIterator

rust 复制代码
#[derive(Debug)]
struct MyList<T>(Vec<T>);            // 自定义集合 MyList(Vec<T>)

impl<T> MyList<T> {
    fn new() -> Self {               // 创建自定义集合
        MyList(Vec::new())
    }
    fn add(&mut self, value: T) {    // 添加元素
        self.0.push(value);
    }
}

impl<T> FromIterator<T> for MyList<T> {                       //FromIterator
    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> Self {  // 实现from_iter方法
        let mut list = MyList::new();                         // 创建自定义集合
        for i in iter {                                       // 循环遍历迭代器,添加到自定义集合
            list.add(i);
        }
        list
    }
}


fn main() {
    // 创建过程:迭代器 ------> 自定义集合
    let mylist1: MyList<i32> = (2..6).collect();
    println!("{:?}", mylist1);

    // 创建过程:集合 ------> 迭代器 ------> 自定义集合
    let mylist2: MyList<i32> = [5, 6, 7, 8].into_iter().collect();
    println!("{:?}", mylist2);

    // 直接调用方法
    let mylist3 = MyList::from_iter([1, 2, 3]);
    println!("{:?}", mylist3);
}
相关推荐
世人万千丶10 小时前
参数管理_Flutter在鸿蒙平台路由参数最佳实践
学习·flutter·华为·harmonyos·鸿蒙
段一凡-华北理工大学12 小时前
向量数据库实战:选型、调优与落地~系列文章12:文本分块策略实战:chunk_size 怎么选?重叠多少?
开发语言·数据库·后端·oracle·rust·工业智能体·高炉智能化
遇乐的果园12 小时前
前端学习笔记-vue加载渲染优化
前端·笔记·学习
遇乐的果园14 小时前
前端学习笔记-vue状态管理优化
前端·笔记·学习
从零开始的代码生活_14 小时前
C++ 继承详解:访问控制、对象模型、菱形继承与设计取舍
开发语言·c++·后端·学习·算法
可乐奶茶sky15 小时前
AI Agent 学习
人工智能·学习
摇滚侠15 小时前
Java 全栈开发实战教程 课程笔记 29-33
笔记
茯苓gao15 小时前
嵌入式开发笔记:EtherCAT协议从硬件到软件完整配置指南——从零搭建一套EtherCAT通信系统
笔记·嵌入式硬件·学习
whyTeaFo16 小时前
GAMES101: Lecture 9: Shading 3(Texture Mapping cont.) ppt笔记
笔记
RD_daoyi17 小时前
外链权重暴跌至13%,品牌提及反超传统链接——2026年不做Digital PR,你的独立站等于隐形
运维·网络·学习·机器学习·搜索引擎