Rust中如何通过函数而非闭包的惯用方式解包Error错误?
解决方案
以下是符合Rust惯用规范的几种实现方式:
方案1:让main函数返回Result(最推荐)
Rust 1.26版本开始支持main函数返回Result类型,是处理顶层错误的首选方式:
use serde_json::Value; use std::error::Error; use ureq; const BASE_URL: &str = "你的服务基础地址"; const LOGIN_URL: &str = "你的登录接口路径"; const API_TOKEN: &str = "你的接口令牌"; fn main() -> Result<(), Box<dyn Error>> { let json = get_json_response(format!("{}{}", BASE_URL, LOGIN_URL).as_str())?; // 此处编写json后续处理逻辑 Ok(()) } fn get_json_response(url: &str) -> Result<Value, Box<dyn Error>> { let resp = ureq::get(url) .set("Authorization", format!("Bearer {}", API_TOKEN).as_str()) .call()? .into_json()?; Ok(resp) }
这种写法下,如果get_json_response返回错误,Rust运行时会自动将错误内容打印到标准错误流,并且以非0状态码退出程序,完全不需要自己编写错误退出的重复逻辑。如果默认的错误输出格式不符合你的业务需求,再选择下面两种方案。
方案2:将错误处理函数改为泛型
你可以把fail函数改为泛型返回值,适配任意Result的成功类型:
fn fail<T>(err: Box<dyn Error>) -> T { eprintln!("Error: failed to get: {}", err); std::process::exit(1); } // 调用时直接传函数名即可正常编译 let json = get_json_response(url).unwrap_or_else(fail);
泛型参数T会在调用时自动推断为匹配的成功类型(此处就是Value),因为std::process::exit返回永不类型!,可以合法转换为任意类型,不会产生无效返回值,也不会触发编译器警告。
方案3:使用闭包包装调用
你已经想到的unwrap_or_else(|e| fail(e))写法也是完全符合规范的,没有额外运行时开销。直接传递函数名不生效的原因是函数指针的类型签名是固定的,而闭包可以根据上下文自动推断返回值类型,利用!可以转换为任意类型的特性完成适配。
内容的提问来源于stack exchange,提问作者marcantonio
相关产品推荐
相关产品推荐

