gpt4 book ai didi

rust - 在动态特征对象上测试迭代器

转载 作者:行者123 更新时间:2023-11-29 08:30:49 25 4
gpt4 key购买 nike

我有两种类型 AB 实现了 Fooable 特性。我有一个 A 数组和一个 B 数组,并在这两个数组上创建一个迭代器,该迭代器具有 Item 类型 &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 特性中公开一些构成 AB 类型对象的数据,并使用它来检查输出的对象是正确的(在我的实际用例中,AB 比我上面的玩具示例更复杂)。

最佳答案

在没有任何更好的想法的情况下,一种可能的解决方法是对 AB 使用 Debug 特性:测试格式化的调试输出是否相等通常等同于 AB 之间的预期概念。

/* ... */
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
})
);

关于rust - 在动态特征对象上测试迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58367487/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com