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

如何在Rust中用链式调用编写简洁的后缀和函数?

Rust 简洁实现后缀和函数的链式调用方案

第一段代码失败的原因

你以为两次rev()相互抵消导致失效?其实不是。问题出在map里捕获了可变变量sum,此时map返回的迭代器闭包是FnMut类型,而这种Map迭代器没有实现DoubleEndedIterator trait,所以根本无法调用后续的rev()方法——这才是代码无法编译运行的核心原因。

第二段代码的冗余问题

第二段代码通过中间collect()转成Vec再反转,确实能运行,但两次collect()会额外分配内存,效率不高,写法也不够简洁。

更简洁的实现方案

方案1:用scan替代map,保留反转思路

scan迭代器可以携带可变状态,并且当原迭代器实现DoubleEndedIterator时,Scan迭代器也会自动实现该trait,这样就能直接链式调用rev(),无需中间collect():

fn suffix_sum(vec: &[i32]) -> Vec<i32> {
    vec.iter()
        .rev()
        .scan(0, |state, &val| {
            *state += val;
            Some(*state)
        })
        .rev()
        .collect()
}

这里把参数从&Vec<i32>改成&[i32],让函数更通用,能接受任意切片类型。

方案2:利用总和直接计算,无需反转

后缀和的本质是:第一个元素是数组总和,第二个是总和减去第一个元素,第三个是总和减去前两个元素……基于这个逻辑,我们可以一次遍历完成计算,效率更高:

fn suffix_sum(vec: &[i32]) -> Vec<i32> {
    let total: i32 = vec.iter().sum();
    vec.iter()
        .scan(total, |state, &val| {
            let res = *state;
            *state -= val;
            Some(res)
        })
        .collect()
}

这个写法完全不需要反转迭代器,只需要一次遍历生成结果,代码更简洁,性能也更好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 18:31:01