【发布时间】:2015-03-08 22:03:15
【问题描述】:
我有一个程序需要检查一个复杂的数据结构,看看它是否有任何缺陷。 (这很复杂,所以我发布示例代码。)所有的检查彼此无关,并且都有自己的模块和测试。
更重要的是,每个检查都有自己的错误类型,其中包含有关每个数字的检查如何失败的不同信息。我正在这样做,而不是仅仅返回一个错误字符串,以便我可以测试错误(这就是为什么Error 依赖于PartialEq)。
到目前为止我的代码
我有 Check 和 Error 的特征:
trait Check {
type Error;
fn check_number(&self, number: i32) -> Option<Self::Error>;
}
trait Error: std::fmt::Debug + PartialEq {
fn description(&self) -> String;
}
还有两个示例检查,以及它们的错误结构。在此示例中,如果数字为负数或偶数,我想显示错误:
#[derive(PartialEq, Debug)]
struct EvenError {
number: i32,
}
struct EvenCheck;
impl Check for EvenCheck {
type Error = EvenError;
fn check_number(&self, number: i32) -> Option<EvenError> {
if number < 0 {
Some(EvenError { number: number })
} else {
None
}
}
}
impl Error for EvenError {
fn description(&self) -> String {
format!("{} is even", self.number)
}
}
#[derive(PartialEq, Debug)]
struct NegativeError {
number: i32,
}
struct NegativeCheck;
impl Check for NegativeCheck {
type Error = NegativeError;
fn check_number(&self, number: i32) -> Option<NegativeError> {
if number < 0 {
Some(NegativeError { number: number })
} else {
None
}
}
}
impl Error for NegativeError {
fn description(&self) -> String {
format!("{} is negative", self.number)
}
}
我知道在这个例子中,两个结构看起来相同,但是在我的代码中,有很多不同的结构,所以我不能合并它们。最后,一个例子main函数,来说明我想做的事情:
fn main() {
let numbers = vec![1, -4, 64, -25];
let checks = vec![
Box::new(EvenCheck) as Box<Check<Error = Error>>,
Box::new(NegativeCheck) as Box<Check<Error = Error>>,
]; // What should I put for this Vec's type?
for number in numbers {
for check in checks {
if let Some(error) = check.check_number(number) {
println!("{:?} - {}", error, error.description())
}
}
}
}
你可以在the Rust playground看到代码。
我尝试过的解决方案
我最接近解决方案的是删除关联类型并让检查返回Option<Box<Error>>。但是,我得到了这个错误:
error[E0038]: the trait `Error` cannot be made into an object
--> src/main.rs:4:55
|
4 | fn check_number(&self, number: i32) -> Option<Box<Error>>;
| ^^^^^ the trait `Error` cannot be made into an object
|
= note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses
因为Error 特征中的PartialEq。到目前为止,Rust 对我来说一直很棒,我真的希望我能够将类型系统弯曲成支持这样的东西!
【问题讨论】:
标签: collections types rust