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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 10:06:01