我有两种实现A
特征的B
和Fooable
类型。我有一个A
和一个B
的数组,并在两个数组上创建了一个迭代器,该迭代器的项目类型为&dyn Fooable
。我想编写一个测试来确认迭代器输出正确的对象,例如:
struct C {
as_array: [A; 2],
bs_arry: [B; 2],
}
impl C {
fn contents_iter(&self) -> FoosIterator {
FoosIterator {
a_iter: (&self.as_array).into_iter(),
b_iter: (&self.bs_arry).into_iter(),
}
}
}
struct FoosIterator<'a> {
a_iter: <&'a [A; 2] as IntoIterator>::IntoIter,
b_iter: <&'a [B; 2] as IntoIterator>::IntoIter,
}
impl<'a> Iterator for FoosIterator<'a> {
type Item = &'a dyn Fooable;
fn next(&mut self) -> Option<Self::Item> {
match self.a_iter.next() {
Some(upper_slot) => Some(upper_slot),
None => self.b_iter.next().map(|x| x as &dyn Fooable),
}
}
}
trait Fooable: std::fmt::Debug {
fn calculate_num(&self) -> i32;
}
#[derive(PartialEq, Debug)]
struct A {
value: i32,
}
impl Fooable for A {
fn calculate_num(&self) -> i32 {
self.value
}
}
#[derive(PartialEq, Debug)]
struct B {
value_1: i32,
value_2: i32,
}
impl Fooable for B {
fn calculate_num(&self) -> i32 {
self.value_1 * 5 + self.value_2
}
}
#[test]
fn test_contents_iter() {
let c = C {
as_array: [A { value: 3 }, A { value: 5 }],
bs_arry: [
B {
value_1: 3,
value_2: 1,
},
B {
value_1: 5,
value_2: 2,
},
],
};
let mut iter = c.contents_iter();
assert_eq!(
*iter
.next()
.expect("Should have initial element from iterator"),
A { value: 3 }
);
assert_eq!(
*iter
.next()
.expect("Should have second element from iterator"),
A { value: 5 }
);
assert_eq!(
*iter
.next()
.expect("Should have third element from iterator"),
B {
value_1: 3,
value_2: 1
}
);
assert_eq!(
*iter
.next()
.expect("Should have fourth element from iterator"),
B {
value_1: 5,
value_2: 2
}
);
}
问题在于类型&dyn Fooable
的对象没有实现PartialEq
特征,因此无法进行相等性比较:
error[E0369]: binary operation `==` cannot be applied to type `dyn Fooable`
--> src/lib.rs:73:5
|
73 | / assert_eq!(
74 | | *iter
75 | | .next()
76 | | .expect("Should have initial element from iterator"),
77 | | A { value: 3 }
78 | | );
| | ^
| | |
| |______dyn Fooable
| A
|
= note: an implementation of `std::cmp::PartialEq` might be missing for `dyn Fooable`
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
据我了解(例如,来自How to test for equality between trait objects?的),无法为动态类型实现此特征。有什么办法可以达到目标呢?我想可以改为以A
特征公开一些构成B
和Fooable
类型的对象的数据,并使用它来检查输出的对象是否正确(在我的实际使用案例A
和B
比上面的我的玩具示例更复杂)。
答案 0 :(得分:0)
在没有更好的主意的情况下,一种可能的解决方法是对A
和B
使用Debug特性:测试格式化的调试输出是否相等通常等于预期的效果。 A
和B
之间的平等概念。
/* ... */
assert_eq!(
format!("{:?}", *iter
.next()
.expect("Should have initial element from iterator")),
format("{:?}", A { value: 3 })
);
assert_eq!(
format!("{:?}", *iter
.next()
.expect("Should have second element from iterator")),
format("{:?}", A { value: 5 })
);
assert_eq!(
format!("{:?}", *iter
.next()
.expect("Should have third element from iterator")),
format("{:?}",
B {
value_1: 3,
value_2: 1
})
);
assert_eq!(
format!("{:?}", *iter
.next()
.expect("Should have third element from iterator")),
format("{:?}",
B {
value_1: 5,
value_2: 2
})
);