使用Result包装非错误函数的惯用Rust方法是什么?

问题描述 投票:0回答:1

我有一个函数将str解析为数字并返回它或错误

fn parse_str<T: FromStr>(text: &str) -> Result<T, SaleError> {
    match text.parse::<T>() {
        Ok(value) => Ok(value),
        _ => Err(SaleError::new(6010, 1999)),
    }
}

SaleError是我的自定义错误结构。

在解析之后,我想在结果值中进行一些其他检查,例如,检查is_sign_positive()的数字是否为正数,如果不是,我想发出Err(SaleError)

由于is_sign_positive()只返回bool,我所做的就是创建这个函数:

fn is_positive(number: f64) -> Result<f64, SaleError> {
    match number.is_sign_positive() {
        true => Ok(number),
        false => Err(SaleError::new(6010, 1999)),
    }
}

现在我可以这样使用它:

let value1 = try!(parse_str::<f64>("123").and_then(is_positive)
                  .or(Err(SaleError::new(6010, 1465))));
let value2 = try!(parse_str::<f64>("321").and_then(is_positive)
                  .or(Err(SaleError::new(6010, 5000))));

这很好用,但请注意我需要SaleErrorvalue1的特定value2实例,所以我使用了or()函数。

现在,因为我总是想要一个特定的错误,而不是一个is_positive返回给我,是否有可能包装is_sign_positive()所以我可以使用它而无需创建函数is_positive

像这样的东西:

let value1 = try!(parse_str::<f64>("123").check_if(|n| n.is_sign_positive())
                  .or(Err(SaleError::new(6010, 1465))));
error-handling rust rust-result
1个回答
1
投票

我可能只是使用if

"123"
    .parse::<f64>()
    .map_err(|_| SaleError(6010, 1999))
    .and_then(|n| {
        if n.is_sign_positive() {
            Ok(n)
        } else {
            Err(SaleError(6010, 1465))
        }
    });

如果你真的想要它,你可以做到:

struct SaleError(i32, i32);

fn main() {
    "123"
        .parse::<f64>()
        .map_err(|_| SaleError(6010, 1999))
        .wonky(SaleError(6010, 1465), |n| n.is_sign_positive());
}

trait Wonky<T, E> {
    fn wonky<F>(self, error: E, f: F) -> Result<T, E>
        where F: FnOnce(&T) -> bool;
}

impl<T, E> Wonky<T, E> for Result<T, E> {
    fn wonky<F>(self, error: E, f: F) -> Result<T, E>
        where F: FnOnce(&T) -> bool
    {
        match self {
            Ok(n) => if f(&n) { Ok(n) } else { Err(error) },
            Err(e) => Err(e),
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.