如何在 Rust 中以惯用的方式将 bool 转换为 Option 或 Result?

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

好像没有办法用

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
5个回答
48
投票

从 Rust 1.50 开始,您可以使用

bool::then
:

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

您可以通过链接

Result
将其转换为
Option::ok_or

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

从 Rust 1.62 开始,您可以使用

bool::then_some
并直接传递值而不是创建闭包:

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));

30
投票

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
功能的一部分。

更新:从 Rust 1.62 开始,此功能已经稳定。


16
投票

这个答案有点过时了。从 Rust 1.50 开始,您可以使用内置的

bool::then
。有关更多信息,请参阅上面的其他答案。


boolinator
板条箱。它为 Boolinator
 定义了 
扩展特征
bool
,它添加了一些有用的方法。例子:

use boolinator::Boolinator;

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

true
值导致
Some(_)
Ok(_)
,而
false
值导致
None
Err(_)
.

关于将这样的功能添加到 RFC 存储库上的std

 有一个问题,但它看起来不会很快发生。


6
投票

使用

if
表达:

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

0
投票

作为标准库函数的替代品。

then
crate 提供了
some
some_with
布尔方法。

use then::Some

// returns Some(value) if my_bool is true
my_bool.some(value); 

// returns Some(value_fn()) if my_bool is true
my_bool.some_with(value_fn); 

免责声明: 我写这个 crate 是因为我觉得

my_bool.some_with(value)
my_bool.some(|| value)
长很烦人。并且使用
_with
后缀更符合惰性评估函数的 Rust 命名。

© www.soinside.com 2019 - 2024. All rights reserved.