trait表示一般的东西,但错误可能是trait实现所特有的

  • 本文关键字:trait 实现 表示 错误 rust
  • 更新时间 :
  • 英文 :


假设我有一个Decoder的特性,并且我有实现这个特性的特定解码器:

pub trait Decoder {
fn do_something(&self) -> Result<(), DoSomethingError>;
}
pub enum DoSomethingError {}
pub struct SpecificDecoder1 {}
impl Decoder for SpecificDecoder1 {
fn do_something(&self) -> Result<(), DoSomethingError> {
todo!()
}
}
pub struct SpecificDecoder2 {}
impl Decoder for SpecificDecoder2 {
fn do_something(&self) -> Result<(), DoSomethingError> {
todo!()
}
}

每个解码器都可能返回特定的错误。然而,我不想在DoSomethingError特性中包含这些特定的错误,因为一些解码器在某些设备上甚至不可用,所以我不希望枚举中出现#cfg(feature="...")的混乱。

我想过

pub trait DoSomethingError {}
fn do_something(&self) -> Result<(), Box<dyn DoSomethingError>> {
Ok(self.do_another_something()?)
}

这样,如果需要的话,我可以将CCD_ 4下变频到特定的错误。然而,Ok(self.do_another_something()?)不起作用。记住,我不想存储字符串,我希望能够以某种方式匹配错误,或者尝试匹配它,所以我不能在字符串上创建UserDefined(String)变体并将每个错误转换为它。

如果您希望每个实现都有不同的错误,您可以定义具有相关错误类型的特征,就像在TryFrom:中一样

pub trait Decoder {
type Error;
fn do_something(&self) -> Result<(), Self::Error>;
}
pub enum SpecificDecoder1Error {}
pub struct SpecificDecoder1 {}
impl Decoder for SpecificDecoder1 {
type Error = SpecificDecoder1Error;
fn do_something(&self) -> Result<(), Self::Error> {
todo!()
}
}
pub enum SpecificDecoder2Error {}
pub struct SpecificDecoder2 {}
impl Decoder for SpecificDecoder2 {
type Error = SpecificDecoder2Error;
fn do_something(&self) -> Result<(), Self::Error> {
todo!()
}
}

但是,如果您希望trait返回泛型类型,则可以返回dynstd::any::any值,并在必要时进行下转换:

pub trait Decoder {
fn do_something(&self) -> Result<(), Box<dyn std::any::Any>>;
}
pub struct SpecificDecoder1Error(u16);
pub struct SpecificDecoder1 {}
impl Decoder for SpecificDecoder1 {
fn do_something(&self) -> Result<(), Box<dyn std::any::Any>> {
Err(Box::new(SpecificDecoder1Error(13)))
}
}
pub struct SpecificDecoder2Error(String);
pub struct SpecificDecoder2 {}
impl Decoder for SpecificDecoder2 {
fn do_something(&self) -> Result<(), Box<dyn std::any::Any>> {
Err(Box::new(SpecificDecoder2Error(
"Specific Error 2".to_string(),
)))
}
}
fn main() {
let dec1 = SpecificDecoder1 {};
let dec2 = SpecificDecoder2 {};
let decs: [&dyn Decoder; 2] = [&dec1, &dec2];
for dec in decs {
let error = dec.do_something().err().unwrap();
if let Some(error1) = error.downcast_ref::<SpecificDecoder1Error>() {
println!("Error from SpecificDecoder1Error: {}", error1.0)
} else if let Some(error2) =
error.downcast_ref::<SpecificDecoder2Error>()
{
println!("Error from SpecificDecoder2Error: {}", error2.0)
} else {
unreachable!()
}
}
}

最新更新