FromIterator 定义了**"如何从一系列元素构建一个容器"**。当你调用迭代器的 .collect() 方法时,编译器底层正是通过 FromIterator trait 来决定最终生成什么类型的数据结构(如 Vec、HashMap、String 等)
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);
}