Rust多Result/多条件场景最优函数签名及错误退出实现方案
现有代码的问题
- 返回值类型错误:你声明函数返回
Result<T, <T as FromStr>::Err>,但函数所有错误分支都会直接退出程序,永远不会返回Err变体,合法路径返回的是T类型而非Result,类型不匹配无法通过编译。 - 内部函数无法捕获外部变量:Rust中用
fn定义的内部函数不能捕获外层作用域的变量,你在error_and_exit中直接使用name、minimum、maximum属于语法错误。 - 错误提示逻辑缺失:解析失败的场景你没有输出具体的错误原因,不利于排查问题。
符合需求的实现
你需要的直接出错退出的版本实现如下,可直接按照你预期的方式调用:
use std::str::FromStr; use std::process; fn parse_between_or_error_out<T: PartialOrd + FromStr + std::fmt::Display>( name: &str, input: &str, min: T, max: T, ) -> T { // 处理解析错误 let val = match input.parse::<T>() { Ok(v) => v, Err(_) => { println!("Error: {} value `{input}` is not a valid number", name); process::exit(1); } }; // 处理范围校验错误 if val < min || val > max { println!("Error: Expected {} amount to be between {min} and {max}", name); process::exit(1); } // 正常返回 println!("- Using {} of {val:.1}/{max}", name); val }
调用示例:
fn blur(image: DynamicImage, amount: &str) -> DynamicImage { let amount = parse_between_or_error_out("blur", amount, 0.0, 10.0); image.blur(amount) }
更规范的推荐写法
不建议在工具函数中直接调用process::exit,会降低函数的通用性,更好的方式是函数返回Result,由上层统一处理错误:
#[derive(Debug)] enum ParseBetweenError { InvalidInput, OutOfRange, } fn parse_between<T: PartialOrd + FromStr + std::fmt::Display>( name: &str, input: &str, min: T, max: T, ) -> Result<T, ParseBetweenError> { let val = input.parse::<T>().map_err(|_| ParseBetweenError::InvalidInput)?; if val < min || val > max { return Err(ParseBetweenError::OutOfRange); } println!("- Using {} of {val:.1}/{max}", name); Ok(val) } // 上层调用时统一处理退出逻辑 fn blur(image: DynamicImage, amount: &str) -> DynamicImage { let amount = parse_between("blur", amount, 0.0, 10.0).unwrap_or_else(|err| { match err { ParseBetweenError::InvalidInput => println!("Error: blur value `{amount}` is not a valid number"), ParseBetweenError::OutOfRange => println!("Error: Expected blur amount to be between 0.0 and 10.0"), } process::exit(1); }); image.blur(amount) }
内容的提问来源于stack exchange,提问作者Webber。
相关产品推荐
相关产品推荐

