跳到主要内容

组合器详解

Rust 标准库组合器速查

or() 和 and()

跟布尔关系的与/或很像,这两个方法会对两个表达式做逻辑组合,最终返回 Option / Result

  • or(),表达式按照顺序求值,若任何一个表达式的结果是 Some 或 Ok,则该值会立刻返回
  • and(),若两个表达式的结果都是 Some 或 Ok,则第二个表达式中的值被返回。若任何一个的结果是 None 或 Err ,则立刻返回。

Rust 组合器速查表

Option · Result · Iterator — 按使用频率排序,示例均可直接运行

场景标签: 链式调用 默认值 类型转换 条件判断 错误处理 收集聚合


Option<T>

#组合器签名简述场景
.map()Option<T> → Option<U>链式调用
.unwrap_or()Option<T> → T默认值
.and_then()Option<T> → Option<U>(可返回 None)链式调用
.unwrap_or_else()惰性求值默认值(闭包)默认值
.ok_or()Option<T> → Result<T, E>类型转换
.filter()条件不满足时变为 None条件判断
.or_else()None 时返回另一个 Option默认值
.is_some() / .is_none()返回 bool条件判断
.as_ref()借用内部值,避免消耗所有权类型转换
.map_or()map + unwrap_or 合一默认值 / 链式调用
.take()取出值,原位置置 None(需 &mut类型转换
.flatten()Option<Option<T>> → Option<T>类型转换

示例

// ① .map() — 变换 Some 内的值,None 穿透
let n: Option<i32> = Some(3);
let s = n.map(|x| x * 2); // Some(6)

// ② .unwrap_or() — 提供默认值
let v: Option<&str> = None;
let s = v.unwrap_or("guest"); // "guest"

// ③ .and_then() — 链式操作,闭包可返回 None(flatMap)
let s = Some("42");
s.and_then(|x| x.parse::<i32>().ok()) // Some(42)

// ④ .unwrap_or_else() — 惰性求值,适合创建代价较大的默认值
let v: Option<Vec<i32>> = None;
v.unwrap_or_else(|| vec![1, 2]) // [1, 2]

// ⑤ .ok_or() — Option 转 Result,None 映射为指定错误
let x: Option<i32> = None;
x.ok_or("missing") // Err("missing")

// ⑥ .filter() — 条件不满足时变为 None
Some(4).filter(|&x| x % 2 == 0) // Some(4)
Some(3).filter(|&x| x % 2 == 0) // None

// ⑦ .or_else() — None 时执行备用逻辑
let a: Option<i32> = None;
a.or_else(|| Some(99)) // Some(99)

// ⑧ .is_some() / .is_none() — 不消耗所有权地检查
let x = Some(1);
if x.is_some() { /* 有值 */ }

// ⑨ .as_ref() — 借用内部值,避免 move
let s = Some(String::from("hi"));
s.as_ref().map(|x| x.len()) // Some(2),s 仍可用

// ⑩ .map_or() — map + unwrap_or 合一
Some(5).map_or(0, |x| x * 2) // 10
None::<i32>.map_or(0, |x| x * 2) // 0

// ⑪ .take() — 取出值,原位置置 None
let mut x = Some(42);
let y = x.take(); // y = Some(42),x = None

// ⑫ .flatten() — 展平嵌套 Option
Some(Some(3)).flatten() // Some(3)
Some(None::<i32>).flatten() // None

Result<T, E>

#组合器签名简述场景
? 运算符Err 时提前返回,自动传播错误处理
.map()变换 Ok 值,Err 穿透链式调用
.map_err()变换 Err 值,统一错误类型错误处理 / 类型转换
.and_then()链式 Result 操作(flatMap)链式调用 / 错误处理
.unwrap_or()Err 时返回默认值默认值
.unwrap_or_else()Err 时惰性求值默认值默认值
.ok()Result<T,E> → Option<T>(丢弃错误)类型转换
.or_else()Err 时执行备用逻辑错误处理
.is_ok() / .is_err()不消耗所有权地检查状态条件判断
.inspect_err()调试打印,不消耗值(Rust 1.76+)错误处理
collect::<Result<V,E>>()迭代器收集,遇到 Err 立即停止收集聚合 / 错误处理

示例

// ① ? 运算符 — 最常用,Err 时自动 return
fn run() -> Result<(), Box<dyn std::error::Error>> {
let n: i32 = "5".parse()?; // 解析失败则提前返回 Err
println!("{n}");
Ok(())
}

// ② .map() — 变换 Ok 值
Ok(2_i32).map(|x| x * 3) // Ok(6)
Err::<i32, &str>("oops").map(|x| x * 3) // Err("oops")

// ③ .map_err() — 统一错误类型
"x".parse::<i32>()
.map_err(|e| format!("parse fail: {e}")) // Err("parse fail: ...")

// ④ .and_then() — 链式校验
"8".parse::<i32>()
.and_then(|n| if n > 0 { Ok(n) } else { Err("非正数".parse::<i32>().unwrap_err()) })

// ⑤ .unwrap_or() — Err 时返回默认值
"bad".parse::<i32>().unwrap_or(0) // 0

// ⑥ .unwrap_or_else() — 惰性默认值
"bad".parse::<i32>().unwrap_or_else(|_| -1) // -1

// ⑦ .ok() — 转为 Option,丢弃错误信息
"42".parse::<i32>().ok() // Some(42)
"x".parse::<i32>().ok() // None

// ⑧ .or_else() — 失败时执行备用逻辑
"x".parse::<i32>()
.or_else(|_| "0".parse::<i32>()) // Ok(0)

// ⑨ .is_ok() / .is_err()
let r = "5".parse::<i32>();
if r.is_ok() { /* 解析成功 */ }

// ⑩ .inspect_err() — 调试用,不消耗值(Rust 1.76+)
"x".parse::<i32>()
.inspect_err(|e| eprintln!("err: {e}"));

// ⑪ collect::<Result<Vec<_>, _>>() — 遇到第一个 Err 就停止
let v: Result<Vec<i32>, _> =
vec!["1", "2", "3"].iter().map(|s| s.parse()).collect();
// Ok([1, 2, 3])

let v: Result<Vec<i32>, _> =
vec!["1", "x", "3"].iter().map(|s| s.parse()).collect();
// Err(ParseIntError)

Iterator

#组合器签名简述场景
.map()逐元素变换,惰性求值链式调用
.filter()保留满足条件的元素条件判断
.collect()收集为 Vec / HashMap / String 等收集聚合
.fold()带初始值的聚合(最通用)收集聚合
.flat_map()map 后展平一层(map + flatten)链式调用
.enumerate()附带下标 (index, value)链式调用
.filter_map()filter + map 合一,None 自动过滤条件判断 / 链式调用
.any() / .all()短路求值,返回 bool条件判断
.take() / .skip()前 N 个 / 跳过前 N 个链式调用
.zip()两迭代器逐对打包链式调用
.chain()拼接两个迭代器链式调用
.find() / .position()找值 Option<&T> / 找下标 Option<usize>条件判断
.sum() / .product()求和 / 求积(需类型标注)收集聚合
.max() / .min()最大 / 最小值,返回 Option收集聚合
.cloned() / .copied()Iterator<&T> → Iterator<T>,消除引用类型转换

示例

// ① .map() — 逐元素变换,惰性,需终止符驱动
vec![1, 2, 3].iter().map(|x| x * 2).collect::<Vec<_>>() // [2, 4, 6]

// ② .filter() — 保留满足条件的元素
vec![1, 2, 3, 4].iter().filter(|&&x| x > 2).collect::<Vec<_>>() // [3, 4]

// ③ .collect() — 收集为各种集合类型
(1..4).collect::<Vec<i32>>() // [1, 2, 3]
(1..4).collect::<std::collections::HashSet<_>>()

// ④ .fold() — 带初始值的通用聚合
vec![1, 2, 3].iter().fold(0, |acc, x| acc + x) // 6
vec![1, 2, 3].iter().fold(1, |acc, x| acc * x) // 6

// ⑤ .flat_map() — map 后展平一层
vec!["a b", "c d"].iter()
.flat_map(|s| s.split(' '))
.collect::<Vec<_>>() // ["a", "b", "c", "d"]

// ⑥ .enumerate() — 附带下标
for (i, v) in vec!["a", "b", "c"].iter().enumerate() {
println!("{i}: {v}"); // 0: a 1: b 2: c
}

// ⑦ .filter_map() — 过滤 + 变换,None 自动丢弃
vec!["1", "x", "3"].iter()
.filter_map(|s| s.parse::<i32>().ok())
.collect::<Vec<_>>() // [1, 3]

// ⑧ .any() / .all() — 短路求值
vec![1, 2, 3].iter().any(|&x| x > 2) // true
vec![2, 4, 6].iter().all(|&x| x % 2 == 0) // true

// ⑨ .take() / .skip()
(0..).take(3).collect::<Vec<_>>() // [0, 1, 2](无限迭代器截断)
(0..5).skip(3).collect::<Vec<_>>() // [3, 4]

// ⑩ .zip() — 两迭代器逐对打包,以较短者为准
let a = vec![1, 2];
let b = vec!["a", "b"];
a.iter().zip(b.iter()).collect::<Vec<_>>() // [(1,"a"), (2,"b")]

// ⑪ .chain() — 拼接两个迭代器
vec![1, 2].iter().chain(vec![3, 4].iter())
.collect::<Vec<_>>() // [1, 2, 3, 4]

// ⑫ .find() / .position()
vec![1, 2, 3].iter().find(|&&x| x > 1) // Some(&2)
vec![1, 2, 3].iter().position(|&x| x == 2) // Some(1)

// ⑬ .sum() / .product() — 需显式类型标注
let s: i32 = vec![1, 2, 3].iter().sum(); // 6
let p: i32 = vec![1, 2, 3].iter().product(); // 6

// ⑭ .max() / .min() — 空迭代器返回 None
vec![3, 1, 4, 1, 5].iter().max() // Some(5)
vec![3, 1, 4, 1, 5].iter().min() // Some(1)

// ⑮ .copied() / .cloned() — 消除迭代器中的引用层
vec![1, 2, 3].iter().copied().collect::<Vec<i32>>() // 适用 Copy 类型
vec!["a".to_string()].iter().cloned().collect::<Vec<String>>() // 适用 Clone 类型

常用组合模式

// 模式 1:解析 + 过滤 + 收集(filter_map 最简洁)
let nums: Vec<i32> = input.split(',')
.filter_map(|s| s.trim().parse().ok())
.collect();

// 模式 2:Option 链式处理
let display = user.get("name") // Option<&str>
.map(|s| s.trim())
.filter(|s| !s.is_empty())
.unwrap_or("匿名");

// 模式 3:Result 链式校验
fn validate(s: &str) -> Result<i32, String> {
s.parse::<i32>()
.map_err(|e| format!("格式错误: {e}"))
.and_then(|n| if n > 0 { Ok(n) } else { Err("必须为正数".into()) })
}

// 模式 4:迭代器批量处理 Result(全成功才返回 Ok)
let results: Result<Vec<i32>, _> = raw_inputs.iter()
.map(|s| s.parse::<i32>())
.collect();

// 模式 5:enumerate + filter_map 找带下标的值
let found: Vec<(usize, i32)> = data.iter()
.enumerate()
.filter_map(|(i, &v)| if v > 10 { Some((i, v)) } else { None })
.collect();

迭代器是惰性的,.map() .filter() 等不会立即执行,只有遇到 .collect() .fold() .sum()终止符时才真正运算。

Option 组合器完整指南

Option 是函数式编程中表示可选值的核心类型,它要么包含一个值(Some(T)),要么不包含值(None)。组合器(Combinator)是一系列链式调用的方法,让你无需显式的 if let/match 就能安全地处理可选值,避免空指针异常。

以下是 Rust 标准库中 Option<T>所有组合器,按功能分类并附带完整示例。

一、基础判断组合器

用于检查 Option 是否包含值,或值是否满足特定条件。

1. is_some()

  • 功能:如果 Option 是 Some,返回 true
  • 签名fn is_some(&self) -> bool
let some_value: Option<i32> = Some(42);
let none_value: Option<i32> = None;

assert!(some_value.is_some());
assert!(!none_value.is_some());

2. is_none()

  • 功能:如果 Option 是 None,返回 true
  • 签名fn is_none(&self) -> bool
let some_value: Option<i32> = Some(42);
let none_value: Option<i32> = None;

assert!(!some_value.is_none());
assert!(none_value.is_none());

3. is_some_and() (Rust 1.70+)

  • 功能:如果 Option 是 Some 且包含的值满足给定谓词,返回 true
  • 签名fn is_some_and(&self, f: impl FnOnce(&T) -> bool) -> bool
let some_value: Option<i32> = Some(42);
let none_value: Option<i32> = None;

assert!(some_value.is_some_and(|&x| x > 0));
assert!(!some_value.is_some_and(|&x| x < 0));
assert!(!none_value.is_some_and(|&x| x > 0));

二、值转换组合器

将 Option 中的值转换为另一种类型,或在值不存在时提供默认值。

1. map()

  • 功能:如果是 Some,应用函数 f 到值上并返回新的 Some;否则返回 None
  • 签名fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U>
let some_value: Option<i32> = Some(42);
let none_value: Option<i32> = None;

assert_eq!(some_value.map(|x| x * 2), Some(84));
assert_eq!(none_value.map(|x| x * 2), None);

2. map_or()

  • 功能:如果是 Some,应用函数 f 到值上;否则返回默认值 default
  • 签名fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U
let some_value: Option<i32> = Some(42);
let none_value: Option<i32> = None;

assert_eq!(some_value.map_or(0, |x| x * 2), 84);
assert_eq!(none_value.map_or(0, |x| x * 2), 0);

3. map_or_else()

  • 功能:如果是 Some,应用函数 f 到值上;否则调用 default 函数获取默认值
  • 签名fn map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U
let some_value: Option<i32> = Some(42);
let none_value: Option<i32> = None;

assert_eq!(some_value.map_or_else(|| 0, |x| x * 2), 84);
assert_eq!(none_value.map_or_else(|| 0, |x| x * 2), 0);

4. and_then() (flat_map)

  • 功能:如果是 Some,应用函数 f 到值上并返回结果(必须是 Option);否则返回 None
  • 签名fn and_then<U, F: FnOnce(T) -> Option<U>>(self, f: F) -> Option<U>
// 链式处理多个可能失败的操作
fn divide(a: i32, b: i32) -> Option<i32> {
if b == 0 { None } else { Some(a / b) }
}

let result = Some(10).and_then(|x| divide(x, 2)).and_then(|x| divide(x, 5));
assert_eq!(result, Some(1));

let result = Some(10).and_then(|x| divide(x, 0)).and_then(|x| divide(x, 5));
assert_eq!(result, None);

三、组合多个 Option

将多个 Option 组合成一个新的 Option。

1. and()

  • 功能:如果 selfSome,返回 optb;否则返回 None
  • 签名fn and<U>(self, optb: Option<U>) -> Option<U>
let some_value: Option<i32> = Some(42);
let none_value: Option<i32> = None;

assert_eq!(some_value.and(Some("hello")), Some("hello"));
assert_eq!(none_value.and(Some("hello")), None);
assert_eq!(some_value.and(None), None);

2. or()

  • 功能:如果 selfSome,返回 self;否则返回 optb
  • 签名fn or(self, optb: Option<T>) -> Option<T>
let some_value: Option<i32> = Some(42);
let none_value: Option<i32> = None;

assert_eq!(some_value.or(Some(100)), Some(42));
assert_eq!(none_value.or(Some(100)), Some(100));
assert_eq!(none_value.or(none_value), None);

3. or_else()

  • 功能:如果 selfSome,返回 self;否则调用 f 函数获取备选 Option
  • 签名fn or_else<F: FnOnce() -> Option<T>>(self, f: F) -> Option<T>
let some_value: Option<i32> = Some(42);
let none_value: Option<i32> = None;

assert_eq!(some_value.or_else(|| Some(100)), Some(42));
assert_eq!(none_value.or_else(|| Some(100)), Some(100));

4. xor()

  • 功能:如果 selfoptb 中恰好有一个是 Some,返回那个 Some;否则返回 None
  • 签名fn xor(self, optb: Option<T>) -> Option<T>
let some_value: Option<i32> = Some(42);
let none_value: Option<i32> = None;

assert_eq!(some_value.xor(none_value), Some(42));
assert_eq!(none_value.xor(some_value), Some(42));
assert_eq!(some_value.xor(some_value), None);
assert_eq!(none_value.xor(none_value), None);

5. zip()

  • 功能:将两个 Option 组合成一个包含元组的 Option;如果有一个是 None,返回 None
  • 签名fn zip<U>(self, other: Option<U>) -> Option<(T, U)>
let some1: Option<i32> = Some(42);
let some2: Option<&str> = Some("hello");
let none_value: Option<i32> = None;

assert_eq!(some1.zip(some2), Some((42, "hello")));
assert_eq!(some1.zip(none_value), None);

6. zip_with() (Rust 1.46+)

  • 功能:将两个 Option 的值应用函数 f 并返回结果;如果有一个是 None,返回 None
  • 签名fn zip_with<U, R, F: FnOnce(T, U) -> R>(self, other: Option<U>, f: F) -> Option<R>
let some1: Option<i32> = Some(42);
let some2: Option<i32> = Some(10);
let none_value: Option<i32> = None;

assert_eq!(some1.zip_with(some2, |a, b| a + b), Some(52));
assert_eq!(some1.zip_with(none_value, |a, b| a + b), None);

四、过滤与扁平化

1. filter()

  • 功能:如果是 Some 且值满足谓词 f,返回 self;否则返回 None
  • 签名fn filter<P: FnOnce(&T) -> bool>(self, f: P) -> Option<T>
let some_value: Option<i32> = Some(42);
let none_value: Option<i32> = None;

assert_eq!(some_value.filter(|&x| x > 0), Some(42));
assert_eq!(some_value.filter(|&x| x < 0), None);
assert_eq!(none_value.filter(|&x| x > 0), None);

2. flatten() (Rust 1.40+)

  • 功能:将嵌套的 Option(Option<Option<T>>)扁平化一层
  • 签名fn flatten(self) -> Option<T>
let nested_some: Option<Option<i32>> = Some(Some(42));
let nested_none1: Option<Option<i32>> = Some(None);
let nested_none2: Option<Option<i32>> = None;

assert_eq!(nested_some.flatten(), Some(42));
assert_eq!(nested_none1.flatten(), None);
assert_eq!(nested_none2.flatten(), None);

五、值提取组合器

从 Option 中提取值,或在值不存在时处理错误。

1. unwrap()

  • 功能:如果是 Some,返回包含的值;否则 panic
  • 签名fn unwrap(self) -> T
let some_value: Option<i32> = Some(42);
assert_eq!(some_value.unwrap(), 42);

// 以下代码会 panic
// let none_value: Option<i32> = None;
// none_value.unwrap();

2. unwrap_or()

  • 功能:如果是 Some,返回包含的值;否则返回默认值 default
  • 签名fn unwrap_or(self, default: T) -> T
let some_value: Option<i32> = Some(42);
let none_value: Option<i32> = None;

assert_eq!(some_value.unwrap_or(0), 42);
assert_eq!(none_value.unwrap_or(0), 0);

3. unwrap_or_else()

  • 功能:如果是 Some,返回包含的值;否则调用 f 函数获取默认值
  • 签名fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T
let some_value: Option<i32> = Some(42);
let none_value: Option<i32> = None;

assert_eq!(some_value.unwrap_or_else(|| 0), 42);
assert_eq!(none_value.unwrap_or_else(|| 0), 0);

4. expect()

  • 功能:如果是 Some,返回包含的值;否则 panic 并显示指定的错误信息
  • 签名fn expect(self, msg: &str) -> T
let some_value: Option<i32> = Some(42);
assert_eq!(some_value.expect("值不存在"), 42);

// 以下代码会 panic 并显示 "值不存在"
// let none_value: Option<i32> = None;
// none_value.expect("值不存在");

5. ok_or()

  • 功能:将 Option 转换为 Result;如果是 Some,返回 Ok(value);否则返回 Err(err)
  • 签名fn ok_or<E>(self, err: E) -> Result<T, E>
let some_value: Option<i32> = Some(42);
let none_value: Option<i32> = None;

assert_eq!(some_value.ok_or("错误"), Ok(42));
assert_eq!(none_value.ok_or("错误"), Err("错误"));

6. ok_or_else()

  • 功能:将 Option 转换为 Result;如果是 Some,返回 Ok(value);否则调用 err 函数获取错误值
  • 签名fn ok_or_else<E, F: FnOnce() -> E>(self, err: F) -> Result<T, E>
let some_value: Option<i32> = Some(42);
let none_value: Option<i32> = None;

assert_eq!(some_value.ok_or_else(|| "错误"), Ok(42));
assert_eq!(none_value.ok_or_else(|| "错误"), Err("错误"));

六、引用与可变引用

将 Option 转换为对其内部值的引用或可变引用,避免所有权转移。

1. as_ref()

  • 功能:将 &Option<T> 转换为 Option<&T>
  • 签名fn as_ref(&self) -> Option<&T>
let some_value: Option<i32> = Some(42);
let ref_value: Option<&i32> = some_value.as_ref();

assert_eq!(ref_value, Some(&42));

2. as_mut()

  • 功能:将 &mut Option<T> 转换为 Option<&mut T>
  • 签名fn as_mut(&mut self) -> Option<&mut T>
let mut some_value: Option<i32> = Some(42);
if let Some(x) = some_value.as_mut() {
*x = 100;
}

assert_eq!(some_value, Some(100));

七、其他实用组合器

1. transpose() (Rust 1.33+)

  • 功能:将 Option<Result<T, E>> 转换为 Result<Option<T>, E>
  • 签名fn transpose(self) -> Result<Option<T>, E>
let some_ok: Option<Result<i32, &str>> = Some(Ok(42));
let some_err: Option<Result<i32, &str>> = Some(Err("错误"));
let none_value: Option<Result<i32, &str>> = None;

assert_eq!(some_ok.transpose(), Ok(Some(42)));
assert_eq!(some_err.transpose(), Err("错误"));
assert_eq!(none_value.transpose(), Ok(None));

2. take()

  • 功能:取出 Option 中的值,将原 Option 置为 None
  • 签名fn take(&mut self) -> Option<T>
let mut some_value: Option<i32> = Some(42);
let taken_value = some_value.take();

assert_eq!(taken_value, Some(42));
assert_eq!(some_value, None);

3. replace()

  • 功能:用新值替换 Option 中的值,返回原来的值
  • 签名fn replace(&mut self, value: T) -> Option<T>
let mut some_value: Option<i32> = Some(42);
let old_value = some_value.replace(100);

assert_eq!(old_value, Some(42));
assert_eq!(some_value, Some(100));

4. copied() (Rust 1.35+)

  • 功能:将 Option<&T> 转换为 Option<T>(要求 T 实现 Copy trait)
  • 签名fn copied(self) -> Option<T>
let value = 42;
let ref_option: Option<&i32> = Some(&value);
let copied_option: Option<i32> = ref_option.copied();

assert_eq!(copied_option, Some(42));

5. cloned() (Rust 1.0+)

  • 功能:将 Option<&T> 转换为 Option<T>(要求 T 实现 Clone trait)
  • 签名fn cloned(self) -> Option<T>
let value = String::from("hello");
let ref_option: Option<&String> = Some(&value);
let cloned_option: Option<String> = ref_option.cloned();

assert_eq!(cloned_option, Some(String::from("hello")));

八、组合器链式调用示例

Option 组合器的强大之处在于可以链式调用,优雅地处理复杂的可选值逻辑:

// 从用户输入中解析年龄,验证是否在合法范围内,然后计算出生年份
fn calculate_birth_year(input: Option<&str>) -> Option<i32> {
input
.and_then(|s| s.parse::<i32>().ok()) // 解析字符串为整数
.filter(|&age| age >= 0 && age <= 120) // 验证年龄范围
.map(|age| 2026 - age) // 计算出生年份
}

assert_eq!(calculate_birth_year(Some("25")), Some(2001));
assert_eq!(calculate_birth_year(Some("150")), None); // 年龄不合法
assert_eq!(calculate_birth_year(Some("abc")), None); // 解析失败
assert_eq!(calculate_birth_year(None), None); // 无输入

总结

Option 组合器让你以声明式的方式处理可选值,避免了繁琐的 if let/match 嵌套,使代码更简洁、更易读、更安全。在实际开发中,应优先使用组合器而非显式的空检查和 panic。

Result 组合器完整指南

Result<T, E> 是 Rust 中表示操作结果的核心类型,它要么包含成功值(Ok(T)),要么包含错误值(Err(E))。组合器(Combinator)让你无需显式的 match 就能安全地处理成功和错误两种情况,是 Rust 错误处理的基石。

以下是 Rust 标准库中 Result<T, E>所有组合器,按功能分类并附带完整示例(基于 Rust 1.77+ 最新版本)。

%% ? 运算符,Err 时提前返回,自动传播、错误处理 %%

一、基础判断组合器

用于检查 Result 是成功还是失败,或值是否满足特定条件。

1. is_ok()

  • 功能:如果 Result 是 Ok,返回 true
  • 签名fn is_ok(&self) -> bool
let ok_value: Result<i32, &str> = Ok(42);
let err_value: Result<i32, &str> = Err("出错了");

assert!(ok_value.is_ok());
assert!(!err_value.is_ok());

2. is_err()

  • 功能:如果 Result 是 Err,返回 true
  • 签名fn is_err(&self) -> bool
let ok_value: Result<i32, &str> = Ok(42);
let err_value: Result<i32, &str> = Err("出错了");

assert!(!ok_value.is_err());
assert!(err_value.is_err());

3. is_ok_and() (Rust 1.70+)

  • 功能:如果 Result 是 Ok 且成功值满足给定谓词,返回 true
  • 签名fn is_ok_and(&self, f: impl FnOnce(&T) -> bool) -> bool
let ok_value: Result<i32, &str> = Ok(42);
let err_value: Result<i32, &str> = Err("出错了");

assert!(ok_value.is_ok_and(|&x| x > 0));
assert!(!ok_value.is_ok_and(|&x| x < 0));
assert!(!err_value.is_ok_and(|&x| x > 0));

4. is_err_and() (Rust 1.70+)

  • 功能:如果 Result 是 Err 且错误值满足给定谓词,返回 true
  • 签名fn is_err_and(&self, f: impl FnOnce(&E) -> bool) -> bool
let ok_value: Result<i32, &str> = Ok(42);
let err_value: Result<i32, &str> = Err("网络错误");

assert!(err_value.is_err_and(|e| e.contains("网络")));
assert!(!err_value.is_err_and(|e| e.contains("数据库")));
assert!(!ok_value.is_err_and(|e| e.contains("网络")));

二、值转换组合器

将 Result 中的成功值或错误值转换为另一种类型。

1. map()

  • 功能:如果是 Ok,应用函数 f 到成功值上并返回新的 Ok;否则返回原 Err
  • 签名fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Result<U, E>
let ok_value: Result<i32, &str> = Ok(42);
let err_value: Result<i32, &str> = Err("出错了");

assert_eq!(ok_value.map(|x| x * 2), Ok(84));
assert_eq!(err_value.map(|x| x * 2), Err("出错了"));

2. map_err()

  • 功能:如果是 Err,应用函数 f 到错误值上并返回新的 Err;否则返回原 Ok
  • 签名fn map_err<F, O: FnOnce(E) -> F>(self, op: O) -> Result<T, F>
let ok_value: Result<i32, &str> = Ok(42);
let err_value: Result<i32, &str> = Err("原始错误");

assert_eq!(ok_value.map_err(|e| format!("错误:{}", e)), Ok(42));
assert_eq!(err_value.map_err(|e| format!("错误:{}", e)), Err("错误:原始错误"));

3. map_or()

  • 功能:如果是 Ok,应用函数 f 到成功值上;否则返回默认值 default
  • 签名fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U
let ok_value: Result<i32, &str> = Ok(42);
let err_value: Result<i32, &str> = Err("出错了");

assert_eq!(ok_value.map_or(0, |x| x * 2), 84);
assert_eq!(err_value.map_or(0, |x| x * 2), 0);

4. map_or_else()

  • 功能:如果是 Ok,应用函数 f 到成功值上;否则调用 default 函数获取默认值
  • 签名fn map_or_else<U, D: FnOnce(E) -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U
let ok_value: Result<i32, &str> = Ok(42);
let err_value: Result<i32, &str> = Err("出错了");

assert_eq!(ok_value.map_or_else(|_| 0, |x| x * 2), 84);
assert_eq!(err_value.map_or_else(|e| e.len() as i32, |x| x * 2), 4);

5. and_then() (flat_map)

  • 功能:如果是 Ok,应用函数 f 到成功值上并返回结果(必须是 Result);否则返回原 Err
  • 签名fn and_then<U, F: FnOnce(T) -> Result<U, E>>(self, f: F) -> Result<U, E>
// 链式处理多个可能失败的操作
fn divide(a: i32, b: i32) -> Result<i32, &'static str> {
if b == 0 { Err("除数不能为零") } else { Ok(a / b) }
}

let result = Ok(10).and_then(|x| divide(x, 2)).and_then(|x| divide(x, 5));
assert_eq!(result, Ok(1));

let result = Ok(10).and_then(|x| divide(x, 0)).and_then(|x| divide(x, 5));
assert_eq!(result, Err("除数不能为零"));

6. or_else()

  • 功能:如果是 Err,应用函数 f 到错误值上并返回结果(必须是 Result);否则返回原 Ok
  • 签名fn or_else<F, O: FnOnce(E) -> Result<T, F>>(self, op: O) -> Result<T, F>
// 错误恢复:如果数据库查询失败,尝试从缓存获取
fn query_db(id: i32) -> Result<String, &'static str> {
Err("数据库连接失败")
}

fn query_cache(id: i32) -> Result<String, &'static str> {
Ok(format!("缓存数据:{}", id))
}

let result = query_db(42).or_else(|_| query_cache(42));
assert_eq!(result, Ok("缓存数据:42"));

7. inspect() (Rust 1.76+)

  • 功能:如果是 Ok,对成功值执行副作用操作(如日志),然后返回原 Result
  • 签名fn inspect<F: FnOnce(&T)>(self, f: F) -> Self
let ok_value: Result<i32, &str> = Ok(42);
let err_value: Result<i32, &str> = Err("出错了");

// 仅在成功时打印日志
ok_value.inspect(|x| println!("成功获取值:{}", x));
err_value.inspect(|x| println!("成功获取值:{}", x)); // 不会执行

8. inspect_err() (Rust 1.76+)

  • 功能:如果是 Err,对错误值执行副作用操作(如日志),然后返回原 Result
  • 签名fn inspect_err<F: FnOnce(&E)>(self, f: F) -> Self
let ok_value: Result<i32, &str> = Ok(42);
let err_value: Result<i32, &str> = Err("出错了");

// 仅在失败时打印日志
ok_value.inspect_err(|e| eprintln!("错误:{}", e)); // 不会执行
err_value.inspect_err(|e| eprintln!("错误:{}", e));

三、组合多个 Result

将多个 Result 组合成一个新的 Result。

1. and()

  • 功能:如果 selfOk,返回 res;否则返回原 Err
  • 签名fn and<U>(self, res: Result<U, E>) -> Result<U, E>
let ok_value: Result<i32, &str> = Ok(42);
let err_value: Result<i32, &str> = Err("出错了");

assert_eq!(ok_value.and(Ok("hello")), Ok("hello"));
assert_eq!(err_value.and(Ok("hello")), Err("出错了"));
assert_eq!(ok_value.and(Err("另一个错误")), Err("另一个错误"));

2. or()

  • 功能:如果 selfOk,返回 self;否则返回 res
  • 签名fn or<F>(self, res: Result<T, F>) -> Result<T, F>
let ok_value: Result<i32, &str> = Ok(42);
let err_value: Result<i32, &str> = Err("出错了");

assert_eq!(ok_value.or(Ok(100)), Ok(42));
assert_eq!(err_value.or(Ok(100)), Ok(100));
assert_eq!(err_value.or(Err("另一个错误")), Err("另一个错误"));

3. xor() (Rust 1.73+)

  • 功能:如果 selfres 中恰好有一个是 Ok,返回那个 Ok;否则返回 Err
  • 签名fn xor(self, res: Result<T, E>) -> Result<T, E> where E: Default
let ok_value: Result<i32, &str> = Ok(42);
let err_value: Result<i32, &str> = Err("出错了");

assert_eq!(ok_value.xor(err_value), Ok(42));
assert_eq!(err_value.xor(ok_value), Ok(42));
assert_eq!(ok_value.xor(ok_value), Err("")); // E::default() 对于 &str 是 ""
assert_eq!(err_value.xor(err_value), Err(""));

四、与 Option 的转换

在 Result 和 Option 之间进行转换。

1. ok()

  • 功能:将 Result 转换为 Option;如果是 Ok,返回 Some(value);否则返回 None
  • 签名fn ok(self) -> Option<T>
let ok_value: Result<i32, &str> = Ok(42);
let err_value: Result<i32, &str> = Err("出错了");

assert_eq!(ok_value.ok(), Some(42));
assert_eq!(err_value.ok(), None);

2. err()

  • 功能:将 Result 转换为 Option;如果是 Err,返回 Some(error);否则返回 None
  • 签名fn err(self) -> Option<E>
let ok_value: Result<i32, &str> = Ok(42);
let err_value: Result<i32, &str> = Err("出错了");

assert_eq!(ok_value.err(), None);
assert_eq!(err_value.err(), Some("出错了"));

3. transpose() (Rust 1.33+)

  • 功能:将 Result<Option<T>, E> 转换为 Option<Result<T, E>>
  • 签名fn transpose(self) -> Option<Result<T, E>>
let ok_some: Result<Option<i32>, &str> = Ok(Some(42));
let ok_none: Result<Option<i32>, &str> = Ok(None);
let err_value: Result<Option<i32>, &str> = Err("出错了");

assert_eq!(ok_some.transpose(), Some(Ok(42)));
assert_eq!(ok_none.transpose(), None);
assert_eq!(err_value.transpose(), Some(Err("出错了")));

五、扁平化与嵌套处理

1. flatten() (Rust 1.70+)

  • 功能:将嵌套的 Result(Result<Result<T, E>, E>)扁平化一层
  • 签名fn flatten(self) -> Result<T, E>
let nested_ok: Result<Result<i32, &str>, &str> = Ok(Ok(42));
let nested_err1: Result<Result<i32, &str>, &str> = Ok(Err("内部错误"));
let nested_err2: Result<Result<i32, &str>, &str> = Err("外部错误");

assert_eq!(nested_ok.flatten(), Ok(42));
assert_eq!(nested_err1.flatten(), Err("内部错误"));
assert_eq!(nested_err2.flatten(), Err("外部错误"));

六、值提取组合器

从 Result 中提取值,或在失败时处理错误。

1. unwrap()

  • 功能:如果是 Ok,返回成功值;否则 panic
  • 签名fn unwrap(self) -> T where E: Debug
let ok_value: Result<i32, &str> = Ok(42);
assert_eq!(ok_value.unwrap(), 42);

// 以下代码会 panic
// let err_value: Result<i32, &str> = Err("出错了");
// err_value.unwrap();

2. unwrap_err()

  • 功能:如果是 Err,返回错误值;否则 panic
  • 签名fn unwrap_err(self) -> E where T: Debug
let err_value: Result<i32, &str> = Err("出错了");
assert_eq!(err_value.unwrap_err(), "出错了");

// 以下代码会 panic
// let ok_value: Result<i32, &str> = Ok(42);
// ok_value.unwrap_err();

3. unwrap_or()

  • 功能:如果是 Ok,返回成功值;否则返回默认值 default
  • 签名fn unwrap_or(self, default: T) -> T
let ok_value: Result<i32, &str> = Ok(42);
let err_value: Result<i32, &str> = Err("出错了");

assert_eq!(ok_value.unwrap_or(0), 42);
assert_eq!(err_value.unwrap_or(0), 0);

4. unwrap_or_else()

  • 功能:如果是 Ok,返回成功值;否则调用 f 函数获取默认值
  • 签名fn unwrap_or_else<F: FnOnce(E) -> T>(self, f: F) -> T
let ok_value: Result<i32, &str> = Ok(42);
let err_value: Result<i32, &str> = Err("出错了");

assert_eq!(ok_value.unwrap_or_else(|_| 0), 42);
assert_eq!(err_value.unwrap_or_else(|e| e.len() as i32), 4);

5. expect()

  • 功能:如果是 Ok,返回成功值;否则 panic 并显示指定的错误信息
  • 签名fn expect(self, msg: &str) -> T where E: Debug
let ok_value: Result<i32, &str> = Ok(42);
assert_eq!(ok_value.expect("操作失败"), 42);

// 以下代码会 panic 并显示 "操作失败:出错了"
// let err_value: Result<i32, &str> = Err("出错了");
// err_value.expect("操作失败");

6. expect_err()

  • 功能:如果是 Err,返回错误值;否则 panic 并显示指定的错误信息
  • 签名fn expect_err(self, msg: &str) -> E where T: Debug
let err_value: Result<i32, &str> = Err("出错了");
assert_eq!(err_value.expect_err("应该失败"), "出错了");

// 以下代码会 panic 并显示 "应该失败:42"
// let ok_value: Result<i32, &str> = Ok(42);
// ok_value.expect_err("应该失败");

7. into_ok() (Rust 1.77+)

  • 功能:将 Result 转换为成功值 T;如果是 Err 则 panic
  • 签名fn into_ok(self) -> T where E: Into<!>
// 适用于错误类型是 !(永不发生)的情况
let ok_value: Result<i32, !> = Ok(42);
assert_eq!(ok_value.into_ok(), 42);

8. into_err() (Rust 1.77+)

  • 功能:将 Result 转换为错误值 E;如果是 Ok 则 panic
  • 签名fn into_err(self) -> E where T: Into<!>
// 适用于成功类型是 !(永不发生)的情况
let err_value: Result<!, &str> = Err("出错了");
assert_eq!(err_value.into_err(), "出错了");

七、引用与可变引用

将 Result 转换为对其内部值的引用或可变引用,避免所有权转移。

1. as_ref()

  • 功能:将 &Result<T, E> 转换为 Result<&T, &E>
  • 签名fn as_ref(&self) -> Result<&T, &E>
let ok_value: Result<i32, &str> = Ok(42);
let ref_value: Result<&i32, &&str> = ok_value.as_ref();

assert_eq!(ref_value, Ok(&42));

2. as_mut()

  • 功能:将 &mut Result<T, E> 转换为 Result<&mut T, &mut E>
  • 签名fn as_mut(&mut self) -> Result<&mut T, &mut E>
let mut ok_value: Result<i32, &str> = Ok(42);
if let Ok(x) = ok_value.as_mut() {
*x = 100;
}

assert_eq!(ok_value, Ok(100));

八、其他实用组合器

1. take()

  • 功能:取出 Result 中的值,将原 Result 置为 Err(E::default())
  • 签名fn take(&mut self) -> Result<T, E> where E: Default
let mut ok_value: Result<i32, &str> = Ok(42);
let taken_value = ok_value.take();

assert_eq!(taken_value, Ok(42));
assert_eq!(ok_value, Err("")); // E::default() 对于 &str 是 ""

2. replace()

  • 功能:用新值替换 Result 中的值,返回原来的值
  • 签名fn replace(&mut self, value: T) -> Result<T, E>
let mut ok_value: Result<i32, &str> = Ok(42);
let old_value = ok_value.replace(100);

assert_eq!(old_value, Ok(42));
assert_eq!(ok_value, Ok(100));

3. copied() (Rust 1.59+)

  • 功能:将 Result<&T, &E> 转换为 Result<T, E>(要求 T 和 E 实现 Copy trait)
  • 签名fn copied<'a, T: Copy, E: Copy>(self) -> Result<T, E>
let value = 42;
let ref_result: Result<&i32, &&str> = Ok(&value);
let copied_result: Result<i32, &str> = ref_result.copied();

assert_eq!(copied_result, Ok(42));

4. cloned() (Rust 1.59+)

  • 功能:将 Result<&T, &E> 转换为 Result<T, E>(要求 T 和 E 实现 Clone trait)
  • 签名fn cloned<'a, T: Clone, E: Clone>(self) -> Result<T, E>
let value = String::from("hello");
let ref_result: Result<&String, &&str> = Ok(&value);
let cloned_result: Result<String, &str> = ref_result.cloned();

assert_eq!(cloned_result, Ok(String::from("hello")));

九、组合器链式调用示例

Result 组合器的强大之处在于可以链式调用,优雅地处理复杂的错误处理逻辑:

// 从用户输入中解析数字,验证范围,然后计算平方根
fn calculate_sqrt(input: &str) -> Result<f64, String> {
input
.parse::<f64>()
.map_err(|e| format!("解析失败:{}", e))
.and_then(|n| {
if n >= 0.0 {
Ok(n)
} else {
Err(format!("负数没有实数平方根:{}", n))
}
})
.map(|n| n.sqrt())
.inspect(|sqrt| println!("计算结果:{}", sqrt))
}

assert!(calculate_sqrt("25").is_ok_and(|&x| (x - 5.0).abs() < 1e-9));
assert_eq!(calculate_sqrt("-4"), Err("负数没有实数平方根:-4".to_string()));
assert!(calculate_sqrt("abc").is_err_and(|e| e.starts_with("解析失败")));

总结

Result 组合器是 Rust 错误处理的核心,让你以声明式的方式处理成功和错误两种情况,避免了繁琐的 match 嵌套和显式的错误检查。在实际开发中,应优先使用组合器而非 unwrap()/expect(),除非你能绝对保证操作不会失败。

Rust Iterator 组合器完整指南

迭代器(Iterator)是 Rust 中处理集合的核心抽象,它允许你以声明式的方式对元素序列进行操作。组合器是迭代器上的一系列方法,它们消费一个迭代器并返回一个新的迭代器,支持无限链式调用,是 Rust 函数式编程风格的基石。

以下是 Rust 标准库中 Iterator trait 的所有组合器(截至 Rust 1.77+),按功能分类并附带完整可运行示例。

一、基础转换组合器

将迭代器中的每个元素转换为另一种形式。

1. map()

  • 功能:对每个元素应用函数 f,返回包含转换后元素的新迭代器
  • 签名fn map<B, F>(self, f: F) -> Map<Self, F> where F: FnMut(Self::Item) -> B
let numbers = vec![1, 2, 3, 4];
let doubled: Vec<i32> = numbers.iter().map(|x| x * 2).collect();
assert_eq!(doubled, vec![2, 4, 6, 8]);

2. map_while() (Rust 1.57+)

  • 功能:对元素应用函数 f,直到返回 None 为止,返回包含成功值的迭代器
  • 签名fn map_while<B, F>(self, f: F) -> MapWhile<Self, F> where F: FnMut(Self::Item) -> Option<B>
let numbers = vec![1, 2, 3, -1, 4, 5];
let positive: Vec<i32> = numbers.into_iter()
.map_while(|x| if x > 0 { Some(x * 2) } else { None })
.collect();
assert_eq!(positive, vec![2, 4, 6]); // 遇到 -1 停止

3. flat_map()

  • 功能:对每个元素应用函数 f(返回迭代器),然后将所有结果迭代器扁平化
  • 签名fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where F: FnMut(Self::Item) -> U, U: IntoIterator
let words = vec!["hello", "world"];
let chars: Vec<char> = words.iter().flat_map(|s| s.chars()).collect();
assert_eq!(chars, vec!['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']);

4. enumerate()

  • 功能:为每个元素添加索引,返回 (索引, 元素) 对的迭代器
  • 签名fn enumerate(self) -> Enumerate<Self>
let fruits = vec!["apple", "banana", "cherry"];
let indexed: Vec<(usize, &str)> = fruits.iter().enumerate().collect();
assert_eq!(indexed, vec![(0, "apple"), (1, "banana"), (2, "cherry")]);

二、过滤与筛选组合器

从迭代器中选择满足特定条件的元素。

1. filter()

  • 功能:保留满足谓词 f 的元素
  • 签名fn filter<P>(self, predicate: P) -> Filter<Self, P> where P: FnMut(&Self::Item) -> bool
let numbers = vec![1, 2, 3, 4, 5, 6];
let even: Vec<i32> = numbers.into_iter().filter(|x| x % 2 == 0).collect();
assert_eq!(even, vec![2, 4, 6]);

2. filter_map()

  • 功能:对每个元素应用函数 f,保留返回 Some 的值
  • 签名fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where F: FnMut(Self::Item) -> Option<B>
let strings = vec!["1", "2", "three", "4", "five"];
let numbers: Vec<i32> = strings.into_iter()
.filter_map(|s| s.parse::<i32>().ok())
.collect();
assert_eq!(numbers, vec![1, 2, 4]);

3. take()

  • 功能:取前 n 个元素,然后停止
  • 签名fn take(self, n: usize) -> Take<Self>
let numbers = vec![1, 2, 3, 4, 5];
let first_three: Vec<i32> = numbers.into_iter().take(3).collect();
assert_eq!(first_three, vec![1, 2, 3]);

4. take_while()

  • 功能:取元素直到谓词 f 返回 false 为止
  • 签名fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where P: FnMut(&Self::Item) -> bool
let numbers = vec![1, 2, 3, -1, 4, 5];
let positive: Vec<i32> = numbers.into_iter()
.take_while(|&x| x > 0)
.collect();
assert_eq!(positive, vec![1, 2, 3]);

5. skip()

  • 功能:跳过前 n 个元素
  • 签名fn skip(self, n: usize) -> Skip<Self>
let numbers = vec![1, 2, 3, 4, 5];
let after_three: Vec<i32> = numbers.into_iter().skip(3).collect();
assert_eq!(after_three, vec![4, 5]);

6. skip_while()

  • 功能:跳过元素直到谓词 f 返回 false 为止
  • 签名fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where P: FnMut(&Self::Item) -> bool
let numbers = vec![-1, -2, 0, 1, 2];
let positive: Vec<i32> = numbers.into_iter()
.skip_while(|&x| x < 0)
.collect();
assert_eq!(positive, vec![0, 1, 2]);

7. step_by() (Rust 1.28+)

  • 功能:从第一个元素开始,每隔 step 个元素取一个
  • 签名fn step_by(self, step: usize) -> StepBy<Self>
let numbers = vec![0, 1, 2, 3, 4, 5, 6];
let even_indices: Vec<i32> = numbers.into_iter().step_by(2).collect();
assert_eq!(even_indices, vec![0, 2, 4, 6]);

三、扁平化与嵌套处理

处理嵌套的迭代器结构。

1. flatten() (Rust 1.29+)

  • 功能:将嵌套的迭代器(Iterator<Item=IntoIterator>)扁平化一层
  • 签名fn flatten(self) -> Flatten<Self> where Self::Item: IntoIterator
let nested = vec![vec![1, 2], vec![3, 4], vec![5, 6]];
let flattened: Vec<i32> = nested.into_iter().flatten().collect();
assert_eq!(flattened, vec![1, 2, 3, 4, 5, 6]);

2. flat_map()

  • 功能:先 mapflatten,是最常用的扁平化组合器
  • 示例见"基础转换组合器"部分

四、组合多个迭代器

将多个迭代器合并或交错在一起。

1. chain()

  • 功能:将两个迭代器连接起来,先迭代完第一个,再迭代第二个
  • 签名fn chain<U>(self, other: U) -> Chain<Self, U::IntoIter> where U: IntoIterator<Item = Self::Item>
let a = vec![1, 2, 3];
let b = vec![4, 5, 6];
let combined: Vec<i32> = a.into_iter().chain(b).collect();
assert_eq!(combined, vec![1, 2, 3, 4, 5, 6]);

2. zip()

  • 功能:将两个迭代器的元素配对,返回元组的迭代器,直到其中一个迭代器结束
  • 签名fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter> where U: IntoIterator
let numbers = vec![1, 2, 3];
let letters = vec!['a', 'b', 'c'];
let zipped: Vec<(i32, char)> = numbers.into_iter().zip(letters).collect();
assert_eq!(zipped, vec![(1, 'a'), (2, 'b'), (3, 'c')]);

3. interleave() (Rust 1.73+)

  • 功能:交错两个迭代器的元素,先取第一个迭代器的一个元素,再取第二个的一个,依此类推
  • 签名fn interleave<U>(self, other: U) -> Interleave<Self, U::IntoIter> where U: IntoIterator<Item = Self::Item>
let a = vec![1, 3, 5];
let b = vec![2, 4, 6];
let interleaved: Vec<i32> = a.into_iter().interleave(b).collect();
assert_eq!(interleaved, vec![1, 2, 3, 4, 5, 6]);

4. intersperse() (Rust 1.71+)

  • 功能:在迭代器的每个元素之间插入一个分隔符
  • 签名fn intersperse(self, separator: Self::Item) -> Intersperse<Self> where Self::Item: Clone
let words = vec!["hello", "world", "rust"];
let with_spaces: String = words.into_iter().intersperse(" ").collect();
assert_eq!(with_spaces, "hello world rust");

5. intersperse_with() (Rust 1.71+)

  • 功能:在迭代器的每个元素之间插入由函数生成的分隔符
  • 签名fn intersperse_with<F>(self, separator: F) -> IntersperseWith<Self, F> where F: FnMut() -> Self::Item
let numbers = vec![1, 2, 3];
let with_commas: String = numbers
.into_iter()
.map(|x| x.to_string())
.intersperse_with(|| ", ".to_string())
.collect();
assert_eq!(with_commas, "1, 2, 3");

五、排序与去重

对迭代器中的元素进行排序或去除重复项。

1. sorted() (Rust 1.77+)

  • 功能:对迭代器中的元素进行排序(要求元素实现 Ord trait)
  • 签名fn sorted(self) -> impl Iterator<Item = Self::Item> where Self::Item: Ord
let numbers = vec![3, 1, 4, 1, 5, 9, 2, 6];
let sorted: Vec<i32> = numbers.into_iter().sorted().collect();
assert_eq!(sorted, vec![1, 1, 2, 3, 4, 5, 6, 9]);

2. sorted_by()

  • 功能:使用自定义比较函数对元素进行排序
  • 签名fn sorted_by<F>(self, compare: F) -> impl Iterator<Item = Self::Item> where F: FnMut(&Self::Item, &Self::Item) -> Ordering
let mut numbers = vec![3, 1, 4, 1, 5, 9, 2, 6];
let sorted_desc: Vec<i32> = numbers.into_iter()
.sorted_by(|a, b| b.cmp(a))
.collect();
assert_eq!(sorted_desc, vec![9, 6, 5, 4, 3, 2, 1, 1]);

3. sorted_by_key()

  • 功能:根据键提取函数生成的键对元素进行排序
  • 签名fn sorted_by_key<K, F>(self, f: F) -> impl Iterator<Item = Self::Item> where K: Ord, F: FnMut(&Self::Item) -> K
let people = vec![("Alice", 30), ("Bob", 25), ("Charlie", 35)];
let sorted_by_age: Vec<(&str, i32)> = people.into_iter()
.sorted_by_key(|&(_, age)| age)
.collect();
assert_eq!(sorted_by_age, vec![("Bob", 25), ("Alice", 30), ("Charlie", 35)]);

4. dedup() (Rust 1.77+)

  • 功能:去除连续的重复元素(要求元素实现 PartialEq trait)
  • 签名fn dedup(self) -> impl Iterator<Item = Self::Item> where Self::Item: PartialEq
let numbers = vec![1, 1, 2, 2, 3, 3, 3, 4];
let deduped: Vec<i32> = numbers.into_iter().dedup().collect();
assert_eq!(deduped, vec![1, 2, 3, 4]);

5. dedup_by() (Rust 1.77+)

  • 功能:使用自定义相等性判断去除连续的重复元素
  • 签名fn dedup_by<F>(self, same_bucket: F) -> impl Iterator<Item = Self::Item> where F: FnMut(&Self::Item, &Self::Item) -> bool
let numbers = vec![1, 3, 5, 2, 4, 6];
// 去除奇偶性相同的连续元素
let deduped: Vec<i32> = numbers.into_iter()
.dedup_by(|a, b| a % 2 == b % 2)
.collect();
assert_eq!(deduped, vec![1, 2]);

6. dedup_by_key() (Rust 1.77+)

  • 功能:根据键提取函数生成的键去除连续的重复元素
  • 签名fn dedup_by_key<K, F>(self, key: F) -> impl Iterator<Item = Self::Item> where K: PartialEq, F: FnMut(&Self::Item) -> K
let people = vec![("Alice", 30), ("Alice", 35), ("Bob", 25), ("Bob", 30)];
// 去除名字相同的连续元素
let deduped: Vec<(&str, i32)> = people.into_iter()
.dedup_by_key(|&(name, _)| name)
.collect();
assert_eq!(deduped, vec![("Alice", 30), ("Bob", 25)]);

六、折叠与聚合

将迭代器中的所有元素聚合为单个值。

1. fold()

  • 功能:从初始值开始,对每个元素应用累加函数,返回最终结果
  • 签名fn fold<B, F>(self, init: B, f: F) -> B where F: FnMut(B, Self::Item) -> B
let numbers = vec![1, 2, 3, 4];
let sum: i32 = numbers.iter().fold(0, |acc, x| acc + x);
assert_eq!(sum, 10);

2. reduce()

  • 功能:与 fold 类似,但使用第一个元素作为初始值,返回 Option(空迭代器返回 None
  • 签名fn reduce<F>(self, f: F) -> Option<Self::Item> where F: FnMut(Self::Item, Self::Item) -> Self::Item
let numbers = vec![1, 2, 3, 4];
let sum: Option<i32> = numbers.into_iter().reduce(|acc, x| acc + x);
assert_eq!(sum, Some(10));

let empty: Vec<i32> = vec![];
let sum_empty: Option<i32> = empty.into_iter().reduce(|acc, x| acc + x);
assert_eq!(sum_empty, None);

3. scan()

  • 功能:与 fold 类似,但保留中间结果,返回包含所有中间状态的迭代器
  • 签名fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where F: FnMut(&mut St, Self::Item) -> Option<B>
let numbers = vec![1, 2, 3, 4];
let partial_sums: Vec<i32> = numbers.into_iter()
.scan(0, |acc, x| {
*acc += x;
Some(*acc)
})
.collect();
assert_eq!(partial_sums, vec![1, 3, 6, 10]);

4. sum()

  • 功能:计算迭代器中所有元素的和
  • 签名fn sum<S>(self) -> S where S: Sum<Self::Item>
let numbers = vec![1, 2, 3, 4];
let sum: i32 = numbers.iter().sum();
assert_eq!(sum, 10);

5. product()

  • 功能:计算迭代器中所有元素的乘积
  • 签名fn product<P>(self) -> P where P: Product<Self::Item>
let numbers = vec![1, 2, 3, 4];
let product: i32 = numbers.iter().product();
assert_eq!(product, 24);

6. count()

  • 功能:计算迭代器中元素的个数
  • 签名fn count(self) -> usize
let numbers = vec![1, 2, 3, 4];
assert_eq!(numbers.iter().count(), 4);

7. max()

  • 功能:返回迭代器中的最大值(要求元素实现 Ord trait)
  • 签名fn max(self) -> Option<Self::Item> where Self::Item: Ord
let numbers = vec![3, 1, 4, 1, 5, 9, 2, 6];
assert_eq!(numbers.into_iter().max(), Some(9));

8. min()

  • 功能:返回迭代器中的最小值(要求元素实现 Ord trait)
  • 签名fn min(self) -> Option<Self::Item> where Self::Item: Ord
let numbers = vec![3, 1, 4, 1, 5, 9, 2, 6];
assert_eq!(numbers.into_iter().min(), Some(1));

9. max_by_key()

  • 功能:根据键提取函数生成的键返回最大值
  • 签名fn max_by_key<K, F>(self, f: F) -> Option<Self::Item> where K: Ord, F: FnMut(&Self::Item) -> K
let people = vec![("Alice", 30), ("Bob", 25), ("Charlie", 35)];
let oldest = people.into_iter().max_by_key(|&(_, age)| age);
assert_eq!(oldest, Some(("Charlie", 35)));

10. min_by_key()

  • 功能:根据键提取函数生成的键返回最小值
  • 签名fn min_by_key<K, F>(self, f: F) -> Option<Self::Item> where K: Ord, F: FnMut(&Self::Item) -> K
let people = vec![("Alice", 30), ("Bob", 25), ("Charlie", 35)];
let youngest = people.into_iter().min_by_key(|&(_, age)| age);
assert_eq!(youngest, Some(("Bob", 25)));

七、条件与短路操作

检查迭代器中的元素是否满足特定条件,支持短路求值。

1. all()

  • 功能:如果所有元素都满足谓词 f,返回 true;否则返回 false(短路)
  • 签名fn all<F>(&mut self, f: F) -> bool where F: FnMut(Self::Item) -> bool
let numbers = vec![2, 4, 6, 8];
assert!(numbers.iter().all(|&x| x % 2 == 0));
assert!(!numbers.iter().all(|&x| x > 5));

2. any()

  • 功能:如果有任何一个元素满足谓词 f,返回 true;否则返回 false(短路)
  • 签名fn any<F>(&mut self, f: F) -> bool where F: FnMut(Self::Item) -> bool
let numbers = vec![1, 3, 5, 7, 8];
assert!(numbers.iter().any(|&x| x % 2 == 0));
assert!(!numbers.iter().any(|&x| x > 10));

3. find()

  • 功能:返回第一个满足谓词 f 的元素(短路)
  • 签名fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where P: FnMut(&Self::Item) -> bool
let numbers = vec![1, 2, 3, 4, 5];
assert_eq!(numbers.iter().find(|&&x| x > 3), Some(&4));
assert_eq!(numbers.iter().find(|&&x| x > 10), None);

4. find_map()

  • 功能:对元素应用函数 f,返回第一个 Some 值(短路)
  • 签名fn find_map<B, F>(&mut self, f: F) -> Option<B> where F: FnMut(Self::Item) -> Option<B>
let strings = vec!["one", "2", "three", "4", "five"];
let first_number = strings.iter().find_map(|s| s.parse::<i32>().ok());
assert_eq!(first_number, Some(2));

5. position()

  • 功能:返回第一个满足谓词 f 的元素的索引(短路)
  • 签名fn position<P>(&mut self, predicate: P) -> Option<usize> where P: FnMut(Self::Item) -> bool
let numbers = vec![1, 2, 3, 4, 5];
assert_eq!(numbers.iter().position(|&x| x > 3), Some(3));
assert_eq!(numbers.iter().position(|&x| x > 10), None);

6. rposition()

  • 功能:从后往前查找,返回最后一个满足谓词 f 的元素的索引(短路)
  • 签名fn rposition<P>(&mut self, predicate: P) -> Option<usize> where P: FnMut(Self::Item) -> bool, Self: ExactSizeIterator + DoubleEndedIterator
let numbers = vec![1, 2, 3, 4, 5, 4, 3, 2, 1];
assert_eq!(numbers.iter().rposition(|&x| x > 3), Some(5));

八、迭代器控制

改变迭代器的行为或顺序。

1. rev()

  • 功能:反转迭代器的顺序(要求迭代器实现 DoubleEndedIterator trait)
  • 签名fn rev(self) -> Rev<Self> where Self: DoubleEndedIterator
let numbers = vec![1, 2, 3, 4];
let reversed: Vec<i32> = numbers.into_iter().rev().collect();
assert_eq!(reversed, vec![4, 3, 2, 1]);

2. cycle()

  • 功能:无限重复迭代器(要求迭代器实现 Clone trait)
  • 签名fn cycle(self) -> Cycle<Self> where Self: Clone
let numbers = vec![1, 2, 3];
let mut cycle = numbers.into_iter().cycle();
assert_eq!(cycle.next(), Some(1));
assert_eq!(cycle.next(), Some(2));
assert_eq!(cycle.next(), Some(3));
assert_eq!(cycle.next(), Some(1)); // 重复

3. peekable()

  • 功能:创建一个可以查看下一个元素而不消费它的迭代器
  • 签名fn peekable(self) -> Peekable<Self>
let mut peekable = vec![1, 2, 3].into_iter().peekable();
assert_eq!(peekable.peek(), Some(&1)); // 查看但不消费
assert_eq!(peekable.next(), Some(1)); // 消费
assert_eq!(peekable.peek(), Some(&2));

4. fuse()

  • 功能:创建一个迭代器,一旦返回 None,就永远返回 None
  • 签名fn fuse(self) -> Fuse<Self>
// 有些迭代器在返回 None 后可能继续返回 Some,fuse 可以防止这种情况
let mut iter = vec![1, 2, 3].into_iter().fuse();
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), Some(3));
assert_eq!(iter.next(), None);
assert_eq!(iter.next(), None); // 永远返回 None

九、副作用与调试

在迭代过程中执行副作用操作,如打印日志。

1. inspect()

  • 功能:对每个元素执行副作用操作,然后返回原元素
  • 签名fn inspect<F>(self, f: F) -> Inspect<Self, F> where F: FnMut(&Self::Item)
let numbers = vec![1, 2, 3, 4];
let sum: i32 = numbers.iter()
.inspect(|x| println!("处理元素:{}", x))
.map(|x| x * 2)
.inspect(|x| println!("加倍后:{}", x))
.sum();
assert_eq!(sum, 20);

十、转换为其他集合类型

将迭代器转换为各种集合类型。

1. collect()

  • 功能:将迭代器转换为实现了 FromIterator trait 的集合类型
  • 签名fn collect<B: FromIterator<Self::Item>>(self) -> B
let numbers = vec![1, 2, 3, 4];
let vec: Vec<i32> = numbers.iter().map(|x| x * 2).collect();
let set: std::collections::HashSet<i32> = numbers.into_iter().collect();
let string: String = vec!['h', 'e', 'l', 'l', 'o'].into_iter().collect();

2. partition()

  • 功能:根据谓词将迭代器分为两个集合
  • 签名fn partition<B, F>(self, f: F) -> (B, B) where B: Default + Extend<Self::Item>, F: FnMut(&Self::Item) -> bool
let numbers = vec![1, 2, 3, 4, 5, 6];
let (even, odd): (Vec<i32>, Vec<i32>) = numbers.into_iter()
.partition(|&x| x % 2 == 0);
assert_eq!(even, vec![2, 4, 6]);
assert_eq!(odd, vec![1, 3, 5]);

3. unzip()

  • 功能:将元组的迭代器拆分为两个独立的集合
  • 签名fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where FromA: Default + Extend<A>, FromB: Default + Extend<B>, Self: Iterator<Item = (A, B)>
let pairs = vec![(1, 'a'), (2, 'b'), (3, 'c')];
let (numbers, letters): (Vec<i32>, Vec<char>) = pairs.into_iter().unzip();
assert_eq!(numbers, vec![1, 2, 3]);
assert_eq!(letters, vec!['a', 'b', 'c']);

十一、综合示例:组合器链式调用

迭代器组合器的真正威力在于可以链式调用,优雅地解决复杂的数据处理问题:

// 计算所有长度大于3的单词中,每个单词的字母出现次数
fn count_letters(words: &[&str]) -> std::collections::HashMap<char, usize> {
words
.iter()
.filter(|&&word| word.len() > 3) // 过滤长度大于3的单词
.flat_map(|&word| word.chars()) // 拆分为字符
.map(|c| c.to_ascii_lowercase()) // 转换为小写
.fold(std::collections::HashMap::new(), |mut acc, c| {
*acc.entry(c).or_insert(0) += 1;
acc
})
}

let words = vec!["hello", "world", "rust", "is", "awesome"];
let counts = count_letters(&words);
assert_eq!(counts[&'h'], 1);
assert_eq!(counts[&'e'], 2);
assert_eq!(counts[&'l'], 3);
assert_eq!(counts[&'o'], 2);

总结

Rust 的迭代器组合器提供了一套强大且表达力极强的工具,让你以声明式的方式处理数据。它们不仅代码简洁易读,而且经过了高度优化,性能通常优于手动循环。

在实际开发中,应优先使用迭代器组合器而非手动循环,这是 Rust 编程的最佳实践之一。

Rust Future 组合器完整指南

Future 是 Rust 异步编程的核心抽象,代表一个尚未完成的异步操作。组合器(Combinator)是一系列链式调用的方法,让你无需显式的 poll 就能组合、转换和控制异步操作,是 Rust 异步编程的重要工具。

重要说明:Rust 标准库的 Future trait 仅定义了核心的 poll 方法,绝大多数实用组合器都在 futures crate(特别是 futures-util)中提供。本文基于 futures 0.3.30+tokio 1.37+ 版本,涵盖所有标准组合器。

注:实际开发中推荐使用 tokio/async-std 提供的更丰富的 Future 组合器

首先,在 Cargo.toml 中添加必要依赖:

[dependencies]
futures = "0.3.30"
tokio = { version = "1.37", features = ["full"] }

导入核心扩展 trait:

use futures::future::{FutureExt, TryFutureExt};
use tokio;

一、基础转换组合器

将 Future 的输出值或错误值转换为另一种类型。

1. map()

  • 功能:如果 Future 成功完成,应用函数到输出值上,返回新的 Future
  • 签名fn map<U, F>(self, f: F) -> Map<Self, F> where F: FnOnce(Self::Output) -> U
#[tokio::main]
async fn main() {
let future = async { 42 };
let mapped = future.map(|x| x * 2);
assert_eq!(mapped.await, 84);
}

2. map_err()

  • 功能:如果 Future 返回错误,应用函数转换错误类型
  • 签名fn map_err<E, F>(self, f: F) -> MapErr<Self, F> where F: FnOnce(Self::Error) -> E
  • 适用:仅用于输出为 Result<T, E> 的 Future(实现了 TryFuture trait)
#[tokio::main]
async fn main() {
let future: Result<i32, &str> = Err("原始错误");
let mapped_err = future.map_err(|e| format!("错误:{}", e));
assert_eq!(mapped_err.await, Err("错误:原始错误".to_string()));
}

3. then()

  • 功能:无论 Future 成功还是失败,都应用函数到结果上,返回新的 Future
  • 签名fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F> where F: FnOnce(Self::Output) -> Fut, Fut: Future
#[tokio::main]
async fn main() {
let success = async { Ok::<i32, &str>(42) };
let failure = async { Err::<i32, &str>("出错了") };

let then_success = success.then(|res| async move {
match res {
Ok(x) => x * 2,
Err(_) => 0,
}
});
assert_eq!(then_success.await, 84);

let then_failure = failure.then(|res| async move {
match res {
Ok(x) => x * 2,
Err(_) => 0,
}
});
assert_eq!(then_failure.await, 0);
}

4. or_else()

  • 功能:如果 Future 返回错误,应用函数进行错误恢复,返回新的 Future
  • 签名fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F> where F: FnOnce(Self::Error) -> Fut, Fut: TryFuture<Ok = Self::Ok>
#[tokio::main]
async fn main() {
// 模拟数据库查询失败,尝试从缓存获取
async fn query_db() -> Result<String, &'static str> {
Err("数据库连接失败")
}

async fn query_cache() -> Result<String, &'static str> {
Ok("缓存数据".to_string())
}

let result = query_db().or_else(|_| query_cache()).await;
assert_eq!(result, Ok("缓存数据".to_string()));
}

5. into_future()

  • 功能:将任意值转换为已经完成的 Future
  • 签名fn into_future(self) -> Ready<Self>
#[tokio::main]
async fn main() {
let value = 42;
let future = value.into_future();
assert_eq!(future.await, 42);
}

二、组合多个 Future

将多个 Future 组合成一个,控制它们的执行顺序和完成方式。

1. join!

  • 功能:并行运行多个 Future,等待所有完成,返回包含所有结果的元组
  • 限制:最多支持 12 个 Future,更多请使用 join_all
#[tokio::main]
async fn main() {
let fut1 = async { 1 };
let fut2 = async { 2 };
let fut3 = async { 3 };

let (res1, res2, res3) = tokio::join!(fut1, fut2, fut3);
assert_eq!((res1, res2, res3), (1, 2, 3));
}

2. join_all()

  • 功能:并行运行迭代器中的所有 Future,等待所有完成,返回结果 Vec
  • 签名fn join_all<I>(iter: I) -> JoinAll<I::Item> where I: IntoIterator, I::Item: Future
use futures::future::join_all;

#[tokio::main]
async fn main() {
let futures = vec![
async { 1 },
async { 2 },
async { 3 },
];

let results = join_all(futures).await;
assert_eq!(results, vec![1, 2, 3]);
}

3. try_join!

  • 功能:并行运行多个 TryFuture只要有一个失败就立即返回错误,否则返回成功值元组
#[tokio::main]
async fn main() {
let fut1 = async { Ok::<i32, &str>(1) };
let fut2 = async { Ok::<i32, &str>(2) };
let fut3 = async { Err::<i32, &str>("出错了") };

let result = tokio::try_join!(fut1, fut2, fut3);
assert_eq!(result, Err("出错了"));
}

4. try_join_all()

  • 功能:并行运行迭代器中的所有 TryFuture,只要有一个失败就立即返回错误
  • 签名fn try_join_all<I>(iter: I) -> TryJoinAll<I::Item> where I: IntoIterator, I::Item: TryFuture
use futures::future::try_join_all;

#[tokio::main]
async fn main() {
let futures = vec![
async { Ok::<i32, &str>(1) },
async { Ok::<i32, &str>(2) },
async { Ok::<i32, &str>(3) },
];

let results = try_join_all(futures).await;
assert_eq!(results, Ok(vec![1, 2, 3]));
}

5. select!

  • 功能:并行运行多个 Future,等待第一个完成的 Future,返回它的结果
  • 特性:会自动取消未完成的 Future(支持取消的类型)
use tokio::time::{sleep, Duration};

#[tokio::main]
async fn main() {
let slow = sleep(Duration::from_millis(100)).map(|_| "慢操作");
let fast = sleep(Duration::from_millis(50)).map(|_| "快操作");

tokio::select! {
res = slow => assert_eq!(res, "慢操作"),
res = fast => assert_eq!(res, "快操作"), // 这个会先完成
}
}

6. select_all()

  • 功能:并行运行迭代器中的所有 Future,返回第一个完成的结果和剩余的 Future
  • 签名fn select_all<I>(iter: I) -> SelectAll<I::Item> where I: IntoIterator, I::Item: Future + Unpin
use futures::future::select_all;
use tokio::time::{sleep, Duration};

#[tokio::main]
async fn main() {
let futures = vec![
sleep(Duration::from_millis(100)).map(|_| 1),
sleep(Duration::from_millis(50)).map(|_| 2),
sleep(Duration::from_millis(150)).map(|_| 3),
];

let (result, index, remaining) = select_all(futures).await;
assert_eq!(result, 2);
assert_eq!(index, 1);
assert_eq!(remaining.len(), 2);
}

7. race()

  • 功能:与 select! 类似,但不返回未完成的 Future,直接返回第一个完成的结果
  • 签名fn race<Fut1, Fut2>(a: Fut1, b: Fut2) -> Race<Fut1, Fut2> where Fut1: Future, Fut2: Future<Output = Fut1::Output>
use futures::future::race;
use tokio::time::{sleep, Duration};

#[tokio::main]
async fn main() {
let slow = sleep(Duration::from_millis(100)).map(|_| "慢操作");
let fast = sleep(Duration::from_millis(50)).map(|_| "快操作");

let result = race(slow, fast).await;
assert_eq!(result, "快操作");
}

8. race_ok!

  • 功能:并行运行多个 TryFuture,等待第一个成功完成的 Future;如果所有都失败,返回最后一个错误
use futures::future::race_ok;
use tokio::time::{sleep, Duration};

#[tokio::main]
async fn main() {
let fut1 = async { Err::<&str, &str>("错误1") };
let fut2 = sleep(Duration::from_millis(50)).map(|_| Ok::<&str, &str>("成功"));
let fut3 = async { Err::<&str, &str>("错误2") };

let result = race_ok!(fut1, fut2, fut3).await;
assert_eq!(result, Ok("成功"));
}

9. zip()

  • 功能:将两个 Future 组合成一个,等待两个都完成,返回结果元组
  • 签名fn zip<Fut>(self, other: Fut) -> Zip<Self, Fut> where Fut: Future
#[tokio::main]
async fn main() {
let fut1 = async { 1 };
let fut2 = async { 2 };

let (res1, res2) = fut1.zip(fut2).await;
assert_eq!((res1, res2), (1, 2));
}

三、错误处理组合器

专门用于处理返回 Result 的 Future(TryFuture)。

1. unwrap()

  • 功能:如果 Future 成功,返回成功值;否则 panic
  • 签名fn unwrap(self) -> Unwrap<Self> where Self::Error: Debug
#[tokio::main]
async fn main() {
let success = async { Ok::<i32, &str>(42) };
assert_eq!(success.unwrap().await, 42);

// 以下代码会 panic
// let failure = async { Err::<i32, &str>("出错了") };
// failure.unwrap().await;
}

2. unwrap_err()

  • 功能:如果 Future 失败,返回错误值;否则 panic
  • 签名fn unwrap_err(self) -> UnwrapErr<Self> where Self::Ok: Debug
#[tokio::main]
async fn main() {
let failure = async { Err::<i32, &str>("出错了") };
assert_eq!(failure.unwrap_err().await, "出错了");

// 以下代码会 panic
// let success = async { Ok::<i32, &str>(42) };
// success.unwrap_err().await;
}

3. unwrap_or()

  • 功能:如果 Future 成功,返回成功值;否则返回默认值
  • 签名fn unwrap_or(self, default: Self::Ok) -> UnwrapOr<Self>
#[tokio::main]
async fn main() {
let success = async { Ok::<i32, &str>(42) };
let failure = async { Err::<i32, &str>("出错了") };

assert_eq!(success.unwrap_or(0).await, 42);
assert_eq!(failure.unwrap_or(0).await, 0);
}

4. unwrap_or_else()

  • 功能:如果 Future 成功,返回成功值;否则调用函数获取默认值
  • 签名fn unwrap_or_else<F>(self, f: F) -> UnwrapOrElse<Self, F> where F: FnOnce(Self::Error) -> Self::Ok
#[tokio::main]
async fn main() {
let failure = async { Err::<i32, &str>("出错了") };
let result = failure.unwrap_or_else(|e| e.len() as i32).await;
assert_eq!(result, 4); // "出错了" 长度是 4
}

5. expect()

  • 功能:如果 Future 成功,返回成功值;否则 panic 并显示指定错误信息
  • 签名fn expect(self, msg: &str) -> Expect<Self> where Self::Error: Debug
#[tokio::main]
async fn main() {
let success = async { Ok::<i32, &str>(42) };
assert_eq!(success.expect("操作失败").await, 42);

// 以下代码会 panic 并显示 "操作失败:出错了"
// let failure = async { Err::<i32, &str>("出错了") };
// failure.expect("操作失败").await;
}

6. ok()

  • 功能:将 TryFuture 转换为 Future<Output=Option<T>>,成功返回 Some(value),失败返回 None
  • 签名fn ok(self) -> Ok<Self>
#[tokio::main]
async fn main() {
let success = async { Ok::<i32, &str>(42) };
let failure = async { Err::<i32, &str>("出错了") };

assert_eq!(success.ok().await, Some(42));
assert_eq!(failure.ok().await, None);
}

7. flatten()

  • 功能:将嵌套的 Future(Future<Output=Future<U>>)扁平化一层
  • 签名fn flatten(self) -> Flatten<Self> where Self::Output: Future
#[tokio::main]
async fn main() {
let nested_future = async { async { 42 } };
let flattened = nested_future.flatten();
assert_eq!(flattened.await, 42);
}

8. transpose()

  • 功能:将 Future<Output=Result<Option<T>, E>> 转换为 Future<Output=Option<Result<T, E>>>
  • 签名fn transpose(self) -> Transpose<Self> where Self::Output: Transpose
#[tokio::main]
async fn main() {
let ok_some: Result<Option<i32>, &str> = Ok(Some(42));
let ok_none: Result<Option<i32>, &str> = Ok(None);
let err: Result<Option<i32>, &str> = Err("出错了");

assert_eq!(ok_some.transpose().await, Some(Ok(42)));
assert_eq!(ok_none.transpose().await, None);
assert_eq!(err.transpose().await, Some(Err("出错了")));
}

四、控制流与实用组合器

改变 Future 的行为或提供实用功能。

1. fuse()

  • 功能:创建一个 Future,一旦完成就永远返回 Poll::Ready(()),防止重复 poll 导致 panic
  • 签名fn fuse(self) -> Fuse<Self>
use futures::task::{noop_waker, Context, Poll};
use std::pin::Pin;

#[tokio::main]
async fn main() {
let mut future = async { 42 }.fuse();
assert_eq!(Pin::new(&mut future).await, 42);

// 再次 poll 不会 panic
let waker = noop_waker();
let mut cx = Context::from_waker(&waker);
assert_eq!(Pin::new(&mut future).poll(&mut cx), Poll::Ready(()));
}

2. inspect()

  • 功能:对 Future 的成功结果执行副作用操作(如日志),然后返回原结果
  • 签名fn inspect<F>(self, f: F) -> Inspect<Self, F> where F: FnOnce(&Self::Output)
#[tokio::main]
async fn main() {
let future = async { 42 }
.inspect(|x| println!("成功获取值:{}", x));

assert_eq!(future.await, 42);
}

3. inspect_err()

  • 功能:对 Future 的错误结果执行副作用操作(如日志),然后返回原结果
  • 签名fn inspect_err<F>(self, f: F) -> InspectErr<Self, F> where F: FnOnce(&Self::Error)
#[tokio::main]
async fn main() {
let future: Result<i32, &str> = Err("出错了")
.inspect_err(|e| eprintln!("错误:{}", e));

assert_eq!(future.await, Err("出错了"));
}

4. shared()

  • 功能:创建一个可以克隆的 Future,多个克隆可以等待同一个 Future 的结果
  • 签名fn shared(self) -> Shared<Self> where Self::Output: Clone
  • 用途:让多个任务共享同一个异步操作的结果,避免重复执行
use tokio::spawn;

#[tokio::main]
async fn main() {
let shared_future = async { 42 }.shared();

let fut1 = shared_future.clone();
let fut2 = shared_future.clone();

let handle1 = spawn(async move { fut1.await });
let handle2 = spawn(async move { fut2.await });

assert_eq!(handle1.await.unwrap(), 42);
assert_eq!(handle2.await.unwrap(), 42);
}

5. boxed()

  • 功能:将 Future 装箱为 Pin<Box<dyn Future<Output = T> + Send>>,用于动态分发
  • 签名fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>> where Self: Send + 'a
use std::future::Future;

fn create_future(flag: bool) -> Pin<Box<dyn Future<Output = i32> + Send>> {
if flag {
async { 42 }.boxed()
} else {
async { 100 }.boxed()
}
}

#[tokio::main]
async fn main() {
assert_eq!(create_future(true).await, 42);
assert_eq!(create_future(false).await, 100);
}

6. boxed_local()

  • 功能:与 boxed() 类似,但不要求 Send,用于单线程运行时
  • 签名fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>> where Self: 'a
use std::future::Future;

fn create_local_future(flag: bool) -> Pin<Box<dyn Future<Output = i32>>> {
if flag {
async { 42 }.boxed_local()
} else {
async { 100 }.boxed_local()
}
}

#[tokio::main(flavor = "current_thread")]
async fn main() {
assert_eq!(create_local_future(true).await, 42);
assert_eq!(create_local_future(false).await, 100);
}

五、常用工具 Future

这些不是组合器,但经常与组合器一起使用,用于创建特定类型的 Future。

1. ready()

  • 功能:创建一个已经完成的 Future,返回指定的值
  • 签名fn ready<T>(value: T) -> Ready<T>
use futures::future::ready;

#[tokio::main]
async fn main() {
let future = ready(42);
assert_eq!(future.await, 42);
}

2. pending()

  • 功能:创建一个永远不会完成的 Future
  • 签名fn pending<T>() -> Pending<T>
use futures::future::{pending, race};
use tokio::time::{sleep, Duration};

#[tokio::main]
async fn main() {
let fut1 = pending::<i32>();
let fut2 = sleep(Duration::from_millis(50)).map(|_| 42);

let result = race(fut1, fut2).await;
assert_eq!(result, 42);
}

3. lazy()

  • 功能:创建一个延迟执行的 Future,只有在第一次 poll 时才调用函数
  • 签名fn lazy<F, R>(f: F) -> Lazy<F> where F: FnOnce() -> R, R: Future
use futures::future::lazy;

#[tokio::main]
async fn main() {
let future = lazy(|| async {
println!("Future 开始执行");
42
});

println!("Future 还没执行");
assert_eq!(future.await, 42); // 这里才会执行
}

六、超时与延迟(Tokio 提供)

这些组合器在 tokio 中提供,用于控制 Future 的执行时间。

1. timeout()

  • 功能:给 Future 设置超时时间,如果在指定时间内没有完成,返回超时错误
  • 签名fn timeout<F>(duration: Duration, future: F) -> Timeout<F> where F: Future
use tokio::time::{timeout, Duration};

#[tokio::main]
async fn main() {
let long_future = tokio::time::sleep(Duration::from_millis(200));
let result = timeout(Duration::from_millis(100), long_future).await;

assert!(result.is_err()); // 超时
}

2. sleep()

  • 功能:创建一个延迟指定时间后完成的 Future
  • 签名fn sleep(duration: Duration) -> Sleep
use tokio::time::{sleep, Duration};

#[tokio::main]
async fn main() {
let start = std::time::Instant::now();
sleep(Duration::from_millis(100)).await;
assert!(start.elapsed() >= Duration::from_millis(100));
}

七、综合示例:组合器链式调用

Future 组合器的强大之处在于可以链式调用,优雅地处理复杂的异步逻辑:

use tokio;
use tokio::time::{timeout, Duration};

// 模拟异步 API 调用
async fn fetch_data(id: i32) -> Result<String, &'static str> {
if id < 0 {
Err("无效的 ID")
} else {
Ok(format!("数据:{}", id))
}
}

#[tokio::main]
async fn main() {
let result = fetch_data(42)
.map_ok(|data| format!("处理后的{}", data)) // 转换成功值
.map_err(|e| format!("API 错误:{}", e)) // 转换错误值
.inspect(|res| println!("API 结果:{:?}", res)) // 打印结果
.timeout(Duration::from_millis(100)) // 设置超时
.await;

match result {
Ok(Ok(data)) => println!("成功:{}", data),
Ok(Err(e)) => eprintln!("错误:{}", e),
Err(_) => eprintln!("请求超时"),
}
}

总结

Future 组合器是 Rust 异步编程的重要工具,它们让你以声明式的方式组合和控制异步操作,避免了回调地狱。虽然现在 async/await 语法已经非常普及,但组合器在动态组合 Future、链式处理结果或错误时仍然非常有用。