Rust函数链遇到None时能否直接返回?可否在链内完成合法性校验?
完全可以把校验逻辑整合到函数链中,无需提前编写独立的if校验代码,核心利用Rust迭代器的短路求值特性就能实现遇到非法值直接提前返回。
你原来用filter_map实现不了该需求的原因是:filter_map遇到None只会跳过当前元素,不会中断整个迭代流程,因此没办法通过None触发整个函数提前返回。你可以将每一步字符处理的结果包装成Result类型,配合try_fold方法实现短路逻辑,优化后的代码如下:
/// Check a Luhn checksum. pub fn is_valid(code: &str) -> bool { code.chars() .rev() .map(|ch| { // 空格直接跳过,返回Ok(None) if ch.is_whitespace() { return Ok(None); } // 转数字成功返回Ok(Some(数字)),失败返回Err触发短路 ch.to_digit(10) .map(Some) .ok_or(()) }) // 用try_fold做聚合,遇到Err立刻终止迭代返回 .try_fold((0u32, 0usize), |(sum, digit_count), digit_res| { let Some(n) = digit_res? else { return Ok((sum, digit_count)); }; // 和原逻辑一致的Luhn计算规则 let add = match digit_count % 2 { 0 => n, _ if n == 9 => n, _ => (n * 2) % 9, }; Ok((sum + add, digit_count + 1)) }) // 最终同时校验长度规则和总和规则 .map(|(sum, digit_count)| digit_count > 1 && sum % 10 == 0) .unwrap_or(false) }
该实现和你原有的代码逻辑完全等价,而且只需要遍历一次字符串,比原有先做全量校验再做计算的两次遍历性能更好。如果可以引入第三方库,也可以用itertools的process_results方法实现更简洁的写法,不需要手写try_fold逻辑。
内容的提问来源于stack exchange,提问作者luceat-lux-vestra
相关产品推荐
相关产品推荐

