返回 Result<(), Box<dyn Error>> 是如何工作的?

3
我见过这样的代码:
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
   Err("March")?
}

而且:

use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
   Err("March".into())
}

但是我真的不明白它们是如何工作的。据我所知,?就像是一个提前返回,当我们遇到错误时立即返回。那么为什么我们还需要Err("March")?呢?为什么不只是Err("March"),因为它已经是函数的最后一个表达式了呢?
对我来说,Err("March".into())甚至更令人困惑。"March".into()返回的是什么,如果它已经返回了一个错误,为什么我们还需要将其包装在Err()中呢?为什么这不会导致奇怪的类型,比如Err(Err())呢?

2
"March" 是一个 &'static str,不是一个 Box<dyn Error> - undefined
1个回答

4
"March".into()具有一个泛型类型,该类型通过推断得到解析。根据返回类型,该泛型类型被推断为Box。
问号操作符起作用是因为它被转换成最终调用错误值上的into()的一些内容。Err("March")? 大致变成了这样的形式
match Err("March") { Ok(val) => val, Err(e) => return Err(e.into()) }

实际的解糖过程更加复杂(主要是因为它还会处理 Option 和 Result 之间的转换),但大致上看起来就像上面的那样。

我在这种情况下试图理解的是,哪个结构体正在实现被 e.into() 调用的 From 特质?这个实现会在 Box 上找到,即 impl<T> From<T> for Box<T> 吗? - undefined
1
@flakes 你是否在寻找impl From<&str> for Box<dyn Error> - undefined
@cafce25 啊,谢谢!看来我看错了实现方式。现在我再仔细想想,那个实现方式确实更有道理。 - undefined
现在我明白了,我可以在我的很多代码中用err.into()来替换Box::new(err) :) - undefined
2
有趣的事实:? 仅使用 From,而不使用 Into。我几天前才了解到这一点,实话实说,我感到相当惊讶。所以 Err 分支应该是 return Err(From::from(e)); - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接