如何在 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 值导致NoneErr(_)

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 错误处理?

HOWTO:使用 gtk (rust-gnome) 回调的惯用 Rust

在Java中安全地将long转换为int

Rust 中的惯用回调