如何创建一个带有迭代器的 Rust 结构?

我想创建一个可以容纳任何类型迭代器的结构。我的实际代码的简化尝试如下:

struct MyStruct<I> {
    my_iter: I,
}

impl<I> MyStruct<I>
where 
    I: std::iter::Iterator<Item = usize>,
{
    fn new(start: usize) -> Self {
        let v: Vec<usize> = vec![start+1, start+2, start+3];
        Self {
            my_iter: v.iter().map(|n| n*2),
        }
    }
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=7c7c68dff49b280bb639738233d357fd

不幸的是,我在编译时收到以下错误:

   Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
  --> src/main.rs:12:22
   |
5  | impl<I> MyStruct<I>
   |      - this type parameter
...
12 |             my_iter: v.iter().map(|n| n*2),
   |                      ^^^^^^^^^^^^^^^^^^^^^ expected type parameter `I`, found struct `Map`
   |
   = note: expected type parameter `I`
                      found struct `Map<std::slice::Iter<'_, usize>, [closure@src/main.rs:12:35: 12:42]>`

error[E0284]: type annotations needed: cannot satisfy `<_ as Iterator>::Item == usize`
  --> src/main.rs:18:13
   |
18 |     let _ = MyStruct::new(2);
   |             ^^^^^^^^^^^^^ cannot satisfy `<_ as Iterator>::Item == usize`
   |
note: required by a bound in `MyStruct::<I>::new`
  --> src/main.rs:7:28
   |
7  |     I: std::iter::Iterator<Item = usize>,
   |                            ^^^^^^^^^^^^ required by this bound in `MyStruct::<I>::new`
8  | {
9  |     fn new(start: usize) -> Self {
   |        --- required by a bound in this

Some errors have detailed explanations: E0284, E0308.
For more information about an error, try `rustc --explain E0284`.
error: could not compile `playground` due to 2 previous errors

我无法从错误中弄清楚如何得到我想要的。

斯维特林·扎列夫

您的实现有两个问题:

  • .iter()方法借用了 vec,因此您试图存储对局部变量的引用,这是不正确的(在释放后使用)
  • 泛型是从“外部”驱动的,但您想从函数内部指定它们,这是不可能的。

所以一种选择是使用盒装迭代器。这将允许您从函数体中指定它并使用任何迭代器:

struct MyStruct {
    my_iter: Box<dyn Iterator<Item = usize>>,
}

impl MyStruct {
    fn new(start: usize) -> Self {
        let v: Vec<usize> = vec![start + 1, start + 2, start + 3];
        Self {
            // note that we are using `.into_iter()` which does not borrow the vec, but converts it to an iterator!
            my_iter: Box::new(v.into_iter().map(|n| n * 2)),
        }
    }
}

如果您坚持使用泛型,另一种选择是从外部传递迭代器:

use std::marker::PhantomData;

struct MyStruct<'l, I> {
    my_iter: I,
    _phantom: PhantomData<&'l I>,
}

impl<'l, I> MyStruct<'l, I>
where
    I: std::iter::Iterator<Item = usize> + 'l,
{
    fn new(iter: I) -> Self {
        Self {
            my_iter: iter,
            _phantom: Default::default(),
        }
    }
}

fn main() {
    let mut data = vec![1, 2, 3];
    let x = MyStruct::new(data.iter().map(|x| *x + 1));
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何创建一个带有迭代器的结构?

如何在Rust中定义一个包含可迭代项的结构上的迭代器?

如何在Rust中将一个结构映射到另一个结构?

如何在 Rust 结构中保存迭代器

如何将结构或元组置于 Rust 迭代器状态?

Rust函数需要一个迭代器,并返回带有变异项的迭代器?

如何克隆带有结构项的向量(rust)?

在 Rust 中使用结构创建哈希图

在Rust中设置结构构造器的类型

Rust中的公共/私有结构

如何创建具有计时时区的通用 Rust 结构?

Rust的结构如何保存和使用对象?

Rust的结构寿命限制如何工作?

如何从Rust中的文件读取结构?

如何在Rust中保存借来的结构

如何在Rust中遍历结构的元素?

Rust中某个结构的惯用迭代器+突变?

为什么Rust的方法文档使用一个单独的构建器结构作为示例?

如何在 Rust 中获取两个结构以使用并共享对另一个结构的引用

有什么方法可以重用相同的结构,还是需要在 Rust 中构建一个新结构?

在Rust中的多个向量中拥有一个结构实例

如何在Rust中定义通用结构而没有其中一个字段属于通用类型?

如何使用serde将结构序列化为另一个Rust数据结构?

如何使用Rust从stdin创建一个高效的char迭代器?

如何在Rust中返回一个引用self的结构?

如何使 Rust 通用结构/特征需要一个 Box<other trait>?

如何在 Rust 中实现一个将自身列表作为字段的结构

C ++如何在结构向量的一个字段上创建迭代器

如何在Rust结构内部创建线程局部变量?