我试图了解如何为自己的类型编写trait
和impl
,以处理一些输入数据。我从一个简单的示例开始,在该示例中,我想使用1, 2, 3, 4
处理输入的trait Processor
。一个实现将跳过第一个元素,并将所有其余输入加倍。因此,它应如下所示:
trait Processor {} // TBD
struct SkipOneTimesTwo;
impl Processor for SkipOneTimesTwo {} // TBD
let numbers = vec![1, 2, 3, 4];
let it = numbers.iter();
let it = Box::new(it);
let proc = SkipOneTimesTwo;
let four_to_eight = proc.process(it);
assert_eq!(Some(4), four_to_eight.next());
assert_eq!(Some(6), four_to_eight.next());
assert_eq!(Some(8), four_to_eight.next());
assert_eq!(None, four_to_eight.next());
所以我的假设是我的特征和相应的实现看起来像这样:trait Processor {
// Arbitrarily convert from `i32` to `u32`
fn process(&self, it: Box<dyn Iterator<Item = i32>>) -> Box<dyn Iterator<Item = u32>>;
}
struct SkipOneTimesTwo;
impl Processor for SkipOneTimesTwo {
fn process(&self, it: Box<dyn Iterator<Item = i32>>) -> Box<dyn Iterator<Item = u32>> {
let p = it.skip(1).map(|i| 2 * (i as u32));
Box::new(p)
}
}
此代码无法按原样工作。我收到以下错误:7 | let four_to_eight = proc.process(it);
| ^^ expected `i32`, found reference
|
= note: expected type `i32`
found reference `&{integer}`
= note: required for the cast to the object type `dyn Iterator<Item = i32>`
如果我的输入数据非常大,我不希望将整个数据集都保存在内存中(使用Iterator
的整个要点),因此我假设使用Iterator<T>
应该从原始输入源流式传输数据,直到将其输入为止。最终汇总或以其他方式处理。但是,我不知道这意味着什么,我需要在此注释的生命周期。最终,我的
Processor
可能保存来自输入的一些中间数据(例如,用于运行平均值计算),因此我可能必须在结构上指定生存期。解决了一些编译器错误,我尝试将
'a
,'static
和'_
生存期添加到dyn Iterator<...>
中,但是我不太清楚如何传递输入迭代器并延迟修改值。这甚至是一种合理的方法吗?我可能可以将输入的
Iterator<Item = i32>
存储在我的struct和impl Iterator<Item = u32> for SkipOneTimesTwo
中,但是随后我可能会失去一些能够绕过Processor
特性的抽象概念。
最佳答案
Rust中的所有迭代器都是惰性的。另外,您不需要使用生存期,只需使用 into_iter()
而不是 iter()
即可编译代码:
trait Processor {
fn process(&self, it: Box<dyn Iterator<Item = i32>>) -> Box<dyn Iterator<Item = u32>>;
}
struct SkipOneTimesTwo;
impl Processor for SkipOneTimesTwo {
fn process(&self, it: Box<dyn Iterator<Item = i32>>) -> Box<dyn Iterator<Item = u32>> {
let p = it.skip(1).map(|i| 2 * (i as u32));
Box::new(p)
}
}
fn main() {
let numbers = vec![1, 2, 3, 4];
let it = numbers.into_iter(); // only change here
let it = Box::new(it);
let pro = SkipOneTimesTwo;
let mut four_to_eight = pro.process(it);
assert_eq!(Some(4), four_to_eight.next());
assert_eq!(Some(6), four_to_eight.next());
assert_eq!(Some(8), four_to_eight.next());
assert_eq!(None, four_to_eight.next());
}
playground
关于rust - 如何为迭代器写trait&impl with lifes?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65781788/