Error handling 如果选项是某个,则返回Err的惯用方法

Error handling 如果选项是某个,则返回Err的惯用方法,error-handling,rust,optional,Error Handling,Rust,Optional,如果遇到None,我们可以提前使用并返回Err: let o = None; let x = o.ok_or(666)?; 但如果我们的预期正好相反呢?如果某事物是某事物,请提前返回: let o = Some(42); if o.is_some() { return Err(666); } 我们能不能用?也这样做?我想这就是让它成为一行并保存字符 您可以使用,将Some(41;转换为Err(666)并将None转换为Ok(())。然而,这不是惯用语,我个人也会坚持使用if is_s

如果遇到
None
,我们可以提前使用并返回
Err

let o = None;
let x = o.ok_or(666)?;
但如果我们的预期正好相反呢?如果某事物是某事物,请提前返回:

let o = Some(42);
if o.is_some() {
    return Err(666);
}

我们能不能用
也这样做?

我想这就是让它成为一行并保存字符

您可以使用,将
Some(41;
转换为
Err(666)
并将
None
转换为
Ok(())
。然而,这不是惯用语,我个人也会坚持使用
if is_some(){return Err(666);}
,因为读者更清楚这是怎么做的

fn foo(o:Option)->结果{
o、 地图或(Ok(()),| | Err(666))?;
好(())
}
fn main(){
println!(“{:?}”,foo(None));
println!(“{:?}”,foo(一些(42));
}
产出:

Ok(())  
Err(666)
Some(123)
None

您还可以创建自己的
ErrOnSome
trait。命名方法,例如
err\u on_some()
这将使读者更清楚、更容易理解正在发生的事情,即使不知道
err\u on_some()
方法的实现

trait ErrOnSome{
fn错误出现在某些(&self,f:f)->结果上
哪里
F:FnOnce()->结果;
}
选项的impl ErrOnSome{
fn错误出现在某些(&self,f:f)->结果上
哪里
F:FnOnce()->结果,
{
匹配自我{
None=>Ok(()),
一些()=>f(),
}
}
}
fn foo(o:选项)->结果{
o、 在某些方面出错(| | err(666))?;
好(())
}
使用相同的
main()
当然会产生相同的输出


编辑:旧答案-我读错了,以为是关于返回
选项的问题

如果包含的值是原语,即创建成本低,那么您可以坚持使用。然而,这不是惯用语,我个人也会坚持使用
if is_some(){return Err(666);}
,因为读者更清楚这是怎么做的

fn foo(o:Option)->Option{
o、 xor(一些(666))?;
有些(())
}
fn main(){
println!(“{:?}”,foo(None));
println!(“{:?}”,foo(一些(42));
}
产出:

Ok(())  
Err(666)
Some(123)
None
我们能不能用
的方式[返回
一些
上的
错误

我不认为它是惯用的,但您可以使用
Option::map
将选项的
Some
变体映射为
Err
。这将把
选项
转换为
选项
,因此您需要将其转换为
结果
,并对其使用

fn x() -> Result<(), i32> {
    let o = Some(42);
    o.map(|_| Err::<(), _>(666)).transpose()?;
    Ok(())
}
fn x()->结果{
设o=Some(42);
o、 map(| | Err::(666)).transpose()?;
好(())
}

Err
上的turbofish提供了必要的类型提示,因为否则Rust无法确定上述
Result
X
,并且结果必须同时具有ok和error类型。我选择了
()
,但它与函数返回类型中的
()
完全无关;它可能是任何其他类型,因为
运算符只关心
结果的错误类型。如果没有if/match语句,那么就知道该方法了。