我不知道如何在标题中一般性地表达该问题,但我在定义 Error 结构来处理第三方库错误时遇到了堆栈溢出错误。这是一个示例代码片段。
pub struct Error(ErrorKind);
impl From<FooError> for Error {
fn from(e: FooError) -> Self {
e.into()
}
}
impl From<BarError> for Error {
fn from(e: BarError) -> Self {
e.into()
}
}
pub enum ErrorKind {
Foo(FooError),
Bar(BarError),
Baz,
}
impl From<FooError> for ErrorKind {
fn from(e: FooError) -> Self {
Self::Foo(e)
}
}
impl From<BarError> for ErrorKind {
fn from(e: BarError) -> Self {
Self::Bar(e)
}
}
#[derive(Debug)]
pub struct FooError;
pub struct BarError;
fn main() {
let foo_e = FooError;
dbg!(&foo_e);
let _e = Error::from(foo_e);
}
当我无意中编写从自定义类型(例如
From<T>
)进行 Error
类型转换的 FooError
实现时,我很惊讶编译器如何理解从 FooError
到 ErrorKind
然后是 Error
的类型转换表情e.into()
。然后我继续前进,直到遇到致命错误。深入研究原因是什么,就是这样。当我将实现更改为;
impl From<FooError> for Error {
fn from(e: FooError) -> Self {
Self(e.into())
}
}
错误消失了。我不认为这是故意的,因为编译器遗漏了这一点。如果这是一个错误,我愿意将其贡献给该语言。如果不是,错误的原因是什么?为什么编译器允许这样做。
任何专业人士的帮助将不胜感激。
这里是游乐场。尝试重现该错误。
很抱歉我的误解。我知道执行
impl From<A> for B
会产生Into<B>
。因此,实现内部的 e.into()
只是递归地调用 from
函数,这会导致堆栈溢出错误。