如何将struct的字段作为`Iterator`而不是`T`元素?

Yur*_*ish 5 rust

我希望struct的字段是Iteratorover T元素,但是Iterator没有type参数.我知道我正在尝试做一些根本错误的事情,尽管如此?

dur*_*a42 8

在Rust中,Iterator(更具体地说Iterator<Item = T>,T迭代时产生的类型在哪里)是一个特征.表示迭代器的类型实现此特征.

这是一个更一般的问题的实例"如何在结构中存储特征的值?".我故意以一种不精确的方式表达这个问题 - 我们真正想要的是存储一个实现该特征类型的值,并且有两种方法可以做到这一点.

把它放在一个盒子里

最简单的方法是使用Box<Iterator<Item = T>>.该Box代表所属的指针,当你有一个指向特性对象,防锈创建了一个"胖指针",包括有关类型的运行时信息.这样,迭代器的具体类型在编译时是未知的.

定义如下:

struct IteratorHolder {
    iter: Box<Iterator<Item = u32>>,
}
Run Code Online (Sandbox Code Playgroud)

用法:

let ih = IteratorHolder { iter: Box::new(0..10) };
println!("{:?}", ih.iter.collect::<Vec<_>>());
Run Code Online (Sandbox Code Playgroud)

泛型

另一种做同样事情的方法是避免在堆上分配任何框,这是使用通用结构.这样我们将有一些类型实现Iterator<Item = T>,具体将在编译时确定.

定义:

struct IteratorHolder<I: Iterator<Item = u32>> {
    iter: I,
}
Run Code Online (Sandbox Code Playgroud)

用法:

let ih = IteratorHolder { iter: 0..10 };
println!("{:?}", ih.iter.collect::<Vec<_>>());
Run Code Online (Sandbox Code Playgroud)

  • 在 Rust 2021 中,“iter: Box&lt;Iterator&lt;Item = u32&gt;&gt;”将不起作用。对于特征对象,我们需要一个显式的“dyn”关键字,即“iter: Box&lt;dyn Iterator&lt;Item = u32&gt;&gt;”。 (8认同)
  • 我希望我们能更新它们。我试图弄清楚如何在结构中存储迭代器,但无法弄清楚。 (4认同)