gpt4 book ai didi

rust - 如何为迭代器写trait&impl with lifes?

转载 作者:行者123 更新时间:2023-12-03 11:34:47 25 4
gpt4 key购买 nike

我试图了解如何为自己的类型编写traitimpl,以处理一些输入数据。我从一个简单的示例开始,在该示例中,我想使用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/

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