error-handling - 为另一个特征项目类型实现一个特征
问题描述
在返回 Result 时,我需要将解析错误转换为我自己的错误类型。简化后,如下所示:
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`
但我不知道Type
这里的确切情况。重点是允许从所有可能的错误中进行转换。
解决方案
类型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 {}
推荐阅读
- javascript - 如何重写这个 batch.delete 函数来为实时数据库工作?
- c# - XmlSerializer:反序列化递归对象图
- angular - 动画在 Angular 项目中不起作用
- spring - 如何使用 Spring Framework 实现多点模式
- xamarin.forms - 无法在 iOS 上的 Xamarin UITest 中使用 ScrollDownTo() 向下滚动到 ScrollView 中不可见的控件
- node.js - 出现“无法在模块外使用 import 语句”错误并且不想升级 Node
- parsing - 解析类 lisp 语言中“Lex 组”的概念
- html - Flexbox flex 属性似乎只适用于 Firefox,不适用于 Chrome 或 Edge
- android - 即使在 Android 10 (API 29) 中卸载应用程序后,如何保持应用程序的存储数据仍然存在
- python - 如何在 R 中使用 Python 代码和包 reticulate 构建一个 lapply 样式的函数?