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

能否扩展Rust的std::result::Result枚举并保留is_ok等原有内置方法?

解决方案说明

Rust 不支持直接扩展外部 crate 定义的枚举(包括标准库的std::result::Result)添加新变体,因此你需要自定义结果枚举承载所有状态,再手动对齐实现原有Result的常用方法即可完全满足你的需求。


具体实现示例

1. 定义自定义扩展枚举

首先定义承载所有业务状态的枚举,包含原有Result的Ok/Err变体和你需要的扩展状态:

use std::io::Error;
use std::result::Result as StdResult;

/// 扩展结果枚举,承载全量业务状态
enum ResultExt<T, E> {
    /// 完全正常,对应原Result::Ok
    Ok(T),
    /// 完全错误,对应原Result::Err
    Err(E),
    /// 运行正常但需要额外检查
    OkButCheckThings(T),
    /// 错误但可重试
    ErrButRetry(E),
}

2. 实现兼容原有Result的方法

在枚举的实现块中对齐Result的常用方法,同时可以按需添加业务专属的判断方法:

impl<T, E> ResultExt<T, E> {
    /// 完全对齐原Result::is_ok,仅完全正常状态返回true
    pub fn is_ok(&self) -> bool {
        matches!(self, Self::Ok(_))
    }

    /// 完全对齐原Result::is_err,仅完全错误状态返回true
    pub fn is_err(&self) -> bool {
        matches!(self, Self::Err(_))
    }

    /// 业务扩展方法:所有非致命错误的成功类状态返回true
    pub fn is_success(&self) -> bool {
        matches!(self, Self::Ok(_) | Self::OkButCheckThings(_))
    }

    /// 对齐原Result::unwrap,所有成功状态返回值,错误状态panic
    pub fn unwrap(self) -> T
    where
        E: std::fmt::Debug,
    {
        match self {
            Self::Ok(v) | Self::OkButCheckThings(v) => v,
            Self::Err(e) | Self::ErrButRetry(e) => panic!("called `ResultExt::unwrap()` on an `Err` value: {:?}", e),
        }
    }

    /// 提供转标准Result的方法,兼容需要标准Result的通用场景
    pub fn into_std_result(self) -> StdResult<T, E> {
        match self {
            Self::Ok(v) | Self::OkButCheckThings(v) => Ok(v),
            Self::Err(e) | Self::ErrButRetry(e) => Err(e),
        }
    }
}

3. 业务使用示例

完全符合你要求的使用方式,既支持单match匹配所有状态,也支持调用is_ok等原有方法:

fn do_stuff() -> ResultExt<u64, Error> {
    // 示例返回需要检查的正常状态
    ResultExt::OkButCheckThings(100)
}

fn check_things() {
    println!("执行额外检查逻辑");
}

fn main() {
    // 单match匹配所有状态
    let var = match do_stuff() {
        ResultExt::Ok(val) => val,
        ResultExt::Err(_) => 0,
        ResultExt::OkButCheckThings(val) => {
            check_things();
            val
        }
        ResultExt::ErrButRetry(_) => {
            // 执行重试逻辑
            0
        }
    };
    dbg!(var);

    // 调用原有is_ok方法
    let var2 = do_stuff();
    if var2.is_ok() {
        println!("完全正常,无需额外检查");
    }
    // 调用扩展方法判断非致命错误
    if var2.is_success() {
        println!("任务无致命错误执行完成");
    }
}

如果需要兼容?运算符,稳定版可以先调用into_std_result()转换为标准Result再使用,nightly版可以通过实现Try trait直接支持?运算符操作自定义枚举。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 01:24:01