You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Rust的collect方法在两个相似函数中表现不同?

Rustlings iterators3练习:为什么两个collect调用返回不同结果?

在rustlings的iterators3练习里,有两个结构几乎一样的函数,调用collect后返回的结果却完全不同:

// 输出: Ok([1, 11, 1426, 3])
fn result_with_list() -> Result<Vec<i32>, DivisionError> {
    let numbers = vec![27, 297, 38502, 81];
    let division_results = numbers.into_iter().map(|n| divide(n, 27));
    let x: Result<Vec<i32>, DivisionError> = division_results.collect();
    println!("{x:?}");
    x
}
// 输出: [Ok(1), Ok(11), Ok(1426), Ok(3)]
fn list_of_results() -> Vec<Result<i32, DivisionError>> {
    let numbers = vec![27, 297, 38502, 81];
    let division_results = numbers.into_iter().map(|n| divide(n, 27));
    let x: Vec<Result<i32, DivisionError>> = division_results.collect();
    println!("{x:?}");
    x
}

核心原因:collect的行为由目标类型决定

collect是迭代器的通用方法,它的行为完全取决于你指定的目标类型——不同类型实现了不同的FromIterator trait,collect就是调用这个trait的方法来生成目标值。

当目标类型是Result<Vec<i32>, DivisionError>时

Result类型的FromIterator实现做了"短路"处理:

  • 遍历迭代器中的每个Result元素,若所有元素都是Ok(value),就把所有value收集成Vec,最后返回Ok(该Vec)
  • 一旦遇到任何一个Err(error),立刻停止遍历,直接返回这个Err(error),不会处理后续元素

当目标类型是Vec<Result<i32>, DivisionError>时

Vec类型的FromIterator实现逻辑很直接:

  • 不管迭代器里的元素是Ok还是Err,都会原样把每个Result元素收集到数组里,完整保留所有结果的状态

反例验证

如果把numbers里的某个数改成不能被27整除的(比如28):

  • result_with_list会直接返回Err(DivisionError),不会收集其他元素的结果
  • list_of_results会返回[Ok(1), Err(DivisionError), Ok(1426), Ok(3)],保留所有迭代产生的Result状态

内容的提问来源于stack exchange,提问作者Bader

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 09:30:49