我正在写一个Error enum
,它表示无法解析从程序参数中获取的值。最初,它看起来像这样:
pub enum LoadingError {
NoArg,
CantParse
}
我希望它能很容易地从一个解析错误转换。str::parse
函数定义如下:
pub fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
FromStr::from_str(self)
}
在我看来,如果我想为从任何FromStr::Err
转换的enum
实现From
trait,我需要我的函数在FromStr
trait上是泛型的。我试着这样做:
pub enum LoadingError<F: FromStr> {
NoArg,
CantParse(F::Err)
}
impl<F: FromStr> From<F::Err> for LoadingError<F> {
fn from(err: F::Err) -> LoadingError<F> {
LoadingError::CantParse(err)
}
}
但是,这不会编译,并返回以下错误:
error[E0119]: conflicting implementations of trait `From<LoadingError<_>>` for type `LoadingError<_>`
--> src/main.rs:15:1
|
15 | impl<F: FromStr> From<F::Err> for LoadingError<F> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- impl<T> From<T> for T;
我真的看不出这两种不同类型签名的实现会有什么冲突,而且我在Rust的核心代码中找不到impl<T> From<T> for T
的定义。
我也试过使用thiserror
crate,导致同样的错误。
#[derive(Error, Debug)]
pub enum LoadingError<F: FromStr> {
#[error("can't find argument")]
NoArg,
#[error("couldn't parse")]
CantParse(#[from] F::Err)
}
我的问题是:如何从FromStr
trait定义的许多Err
中的任何一个实现我的类型的From
trait?
1条答案
按热度按时间2w3kk1z51#
首先,
impl<T> From<T> for T
在这里。其次,任何类型都可以是
FromStr::Err
,包括LoadingError
。如果可以创建一个只对FromStr::Err
中使用的类型起作用的impl,那么就可以通过编写一个FromStr
impl来从crate外部更改代码的含义,该impl使用了一个错误类型,而您认为该错误类型在FromStr::Err
中没有使用。相反,您应该在您正在寻找的实际错误类型上创建
From
imps,如ParseIntError
。或者,您可以创建一个方法将任何错误转换为
LoadingError
,并仅在parse
的结果上使用它。你可以这样使用:
在错误类型上使用泛型可能会有问题,因此您可能希望存储trait对象(或使用trait对象作为泛型)。