rust 从Result< T,T>获取值T

发布时间 2023-08-28 12:51:09作者: CrossPython

问:

我有一个函数:

fn foo<i32>(x: i32) -> Result<i32, i32> {
...
}

  

我想把结果的值提取到一个变量中,不管它是Ok还是Err。我可以这样做:

let val = match foo(10) {
Ok(i) => i,
Err(i) => i,
}

  

想知道是否有一个“更干净”或更“习惯”的方法来这样做,或者这是最好的方法

 

答1,

let (Ok(my_var)|Err(my_var)) = foo(5);
// Can use `my_var` here.

  

 

答2

fn unwrap_either<T>(result: Result<T, T>) -> T {
    result.unwrap_or_else(|e| e)
}

  

答3

没有内置的实用程序方法可以完全做到这一点;我会说你提供的比赛是完全可以接受的。
如果你经常使用这个模式,你可以在Result上实现你自己的扩展:

trait ResultUnwrapEitherExt {
    type Value;
    
    fn unwrap_either(self) -> Self::Value;
}
impl<T> ResultUnwrapEitherExt for Result<T, T> {
    type Value = T;
    
    fn unwrap_either(self) -> T {
        match self {
            Ok(v) => v,
            Err(v) => v,
        }
    }
}

  

现在你在任何地方use这个trait,你可以简单地做foo(10).unwrap_either()
作为旁注,the discriminant is not checked when compiled with optimizations(例如在释放模式中),因为它是冗余检查。对于OkErr变体,

有效载荷存储在相同的位置,因此优化器将发出简单地获取该位置的值的代码,完全忽略判别式。