我需要在返回结果时将解析错误转换为我自己的错误类型。简化后,它看起来像下面这样:
enum MyError {
Parse,
...,
}
fn process<R: FromStr>(s: &str) -> Result<(), MyError> {
Ok(s.parse::<R>()?)
}
要使上述工作正常,应实现 From 特征。这不起作用:
impl From<std::str::FromStr::Err> for MyError {
fn from(e: std::str::FromStr::Err) -> MyError {
MyError::Parse
}
}
编译器诊断:
help: use fully-qualified syntax: `<Type as std::str::FromStr>::Err`
但我不知道这里的确切类型
。重点是允许从所有可能的错误中进行转换。
最佳答案
类型FromStr::Err
是 FromStr
的关联类型特征。 FromStr
的每一次实现有自己的关联类型,而且这种类型是完全不受约束的——它可以是任何类型。这意味着您需要从任何类型转换为 MyError
实现你想要的:
impl<T> From<T> for MyError {
fn from(e: T) -> MyError {
MyError::Parse
}
}
但是,一致性规则不允许此实现 - 它与 From<T>
的实现冲突对于任何类型 T
在标准库中。即使这个实现被允许,它也不会真正做你想做的事——任何错误类型都会被转换成MyError::Parse
。 ,而不仅仅是解析错误。
一种可能的解决方法是为解析错误类型引入标记特征:
trait ParseError {}
impl<T: ParseError> From<T> for MyError {
fn from(e: T) -> MyError {
MyError::Parse
}
}
然后您可以为所有解析错误类型实现此标记特征:
impl ParseError for std::str::ParseBoolError {}
impl ParseError for std::num::ParseFloatError {}
impl ParseError for std::num::ParseIntError {}
impl ParseError for std::net::AddrParseError {}
impl ParseError for std::char::ParseCharError {}
关于error-handling - 为另一个特征项类型实现一个特征,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56316382/