如何在 Rust 中惯用地将 bool 转换为 Option 或 Result?
Posted
技术标签:
【中文标题】如何在 Rust 中惯用地将 bool 转换为 Option 或 Result?【英文标题】:How do I idiomatically convert a bool to an Option or Result in Rust? 【发布时间】: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
最短的代码是什么?
【问题讨论】:
【参考方案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
值导致None
或Err(_)
。
RFC 存储库中有一个issue about adding functionality like this to std
,但看起来不会很快发生。
【讨论】:
【参考方案4】:使用if
表达式:
if my_bool Ok(()) else Err(MyError::False)
【讨论】:
以上是关于如何在 Rust 中惯用地将 bool 转换为 Option 或 Result?的主要内容,如果未能解决你的问题,请参考以下文章
如何最好地将 VARIANT_BOOL 转换为 C++ bool?
编译器是不是应该正确地将 bool 中的任意非零值解释为 true?
如何使用适用于 DynamoDb 的 AWS Rust 开发工具包编写惯用的 Rust 错误处理?