【发布时间】:2020-02-10 12:43:12
【问题描述】:
我有两种类型 A 和 B 实现了 Fooable 特征。我有一个As 数组和一个Bs 数组,并在这两个数组上创建一个迭代器,该迭代器的项目类型为&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?),无法为动态类型实现此特征。有什么办法可以达到这里的目标吗?我想可以改为在Fooable 特征中公开构成A 和B 类型对象的一些数据,并使用它来检查输出的对象是否正确(在我的实际用例中@987654337 @s 和 Bs 比我上面的玩具示例更复杂)。
【问题讨论】:
-
看来How to get a reference to a concrete type from a trait object? 的答案可能会回答您的问题。如果没有,请edit您的问题来解释差异。否则,我们可以将此问题标记为已回答。
-
在我的用例中,“create_vector”对象没有静态生命周期,我相信这意味着不能通过 Any?我已经相应地编辑了问题
-
静态生命周期在一种安全、高效的内存管理语言中似乎没有吸引力——这似乎是不合理的。这两件事虽然相关,但在这种情况下彼此无关。
标签: rust