【问题标题】:How do I idiomatically convert a bool to an Option or Result in Rust?如何在 Rust 中惯用地将 bool 转换为 Option 或 Result?
【发布时间】:2019-07-17 09:21:38
【问题描述】:

使用std似乎没有办法进行这种单行转换。

我不喜欢这种冗长:

match my_bool {
    true => Ok(()),
    false => Err(MyError::False),
}

我想用单线,例如:

let my_bool = true;
let my_option = my_bool.to_option(MyObject{}); // true => MyObject{}, false => None
let my_result = my_bool.to_result(MyObject{}, MyError{}); // true => MyObject{}, false => MyError{}

最短的代码是什么?

【问题讨论】:

    标签: types casting rust type-conversion


    【解决方案1】:

    bool.then_some() 这样做:

    let my_bool = true;
    let my_option = my_bool.then_some(MyObject{});
    let my_result = my_bool.then_some(MyObject{}).ok_or(MyError{});
    

    在撰写本文时,这仍然是实验性 bool_to_option 功能的一部分。

    【讨论】:

      【解决方案2】:

      从 Rust 1.50 开始,您可以使用 bool::then:

      assert_eq!(false.then(|| val), None);
      assert_eq!(true.then(|| val), Some(val));
      

      您可以通过链接Option::ok_or 将其转换为Result

      assert_eq!(false.then(|| val).ok_or(err), Err(err));
      assert_eq!(true.then(|| val).ok_or(err), Ok(val));
      

      在 nightly 上,您可以使用 bool::then_some 并直接传递一个值,而不是创建一个闭包:

      #![feature(bool_to_option)]
      
      assert_eq!(false.then_some(val), None);
      assert_eq!(true.then_some(val), Some(val));
      

      或者,您可以使用Option::filter

      assert_eq!(Some(obj).filter(|_| false), None);
      assert_eq!(Some(obj).filter(|_| true).ok_or(err), Ok(obj));
      

      【讨论】:

        【解决方案3】:

        这个答案有些过时了。从 Rust 1.50 开始,您可以使用内置的 bool::then。有关详细信息,请参阅下面的其他答案。


        boolinator crate。它为bool 定义了the extension trait Boolinator,这增加了几个有用的方法。示例:

        use boolinator::Boolinator;
        
        my_bool.as_some(MyObject {});                // Option<MyObject>
        my_bool.as_result(MyObject {}, MyError {});  // Result<MyObject, MyError>
        

        true 值导致Some(_)Ok(_),而false 值导致NoneErr(_)

        RFC 存储库中有一个issue about adding functionality like this to std,但看起来不会很快发生。

        【讨论】:

          【解决方案4】:

          使用if 表达式:

          if my_bool { Ok(()) } else { Err(MyError::False) }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-05-05
            • 2018-12-22
            • 1970-01-01
            • 1970-01-01
            • 2019-08-07
            • 1970-01-01
            • 2016-08-10
            • 1970-01-01
            相关资源
            最近更新 更多