我认为这就是让它成为单行并保存字符。
您可以使用map_or(),将Some(_) 转换为Err(666),将None 转换为Ok(())。但是,这不是惯用的,我个人也会坚持if is_some() { return Err(666); },因为这对读者来说更清楚。
fn foo(o: Option<i32>) -> Result<(), i32> {
o.map_or(Ok(()), |_| Err(666))?;
Ok(())
}
fn main() {
println!("{:?}", foo(None));
println!("{:?}", foo(Some(42)));
}
输出:
Ok(())
Err(666)
您还可以创建自己的 ErrOnSome 特征。命名方法,例如err_on_some() 即使不知道 err_on_some() 方法的实现,读者也会更加清楚和假设发生了什么。
trait ErrOnSome {
fn err_on_some<F, E>(&self, f: F) -> Result<(), E>
where
F: FnOnce() -> Result<(), E>;
}
impl<T> ErrOnSome for Option<T> {
fn err_on_some<F, E>(&self, f: F) -> Result<(), E>
where
F: FnOnce() -> Result<(), E>,
{
match self {
None => Ok(()),
Some(_) => f(),
}
}
}
fn foo(o: Option<i32>) -> Result<(), i32> {
o.err_on_some(|| Err(666))?;
Ok(())
}
使用相同的main() 当然会产生相同的输出。
编辑:旧答案 - 我误读并认为这是关于返回 Option
如果包含的值是一个原始值,即创建的成本很低,那么您可以坚持使用xor()。但是,这不是惯用的,我个人也会坚持使用if is_some() { return Err(666); },因为这对读者来说更清楚。
fn foo(o: Option<i32>) -> Option<()> {
o.xor(Some(666))?;
Some(())
}
fn main() {
println!("{:?}", foo(None));
println!("{:?}", foo(Some(42)));
}
输出:
Some(123)
None