【问题标题】:Construct a struct that holds a generic iterator of i32 from 'from_iter'?构造一个结构,该结构包含来自 \'from_iter\' 的 i32 通用迭代器?
【发布时间】:2023-02-22 05:21:55
【问题描述】:

我想知道您是否可以从 from_iter 创建一个包含通用迭代器(比如 i32)的结构。

我试过this

use std::iter::FromIterator;

struct IntIterator<T: Iterator<Item = i32>> {
    iter: T,
}

impl<T: Iterator<Item = i32>> FromIterator<i32> for IntIterator<T> {
    fn from_iter<I: IntoIterator<Item = i32>>(iter: I) -> Self {
        IntIterator {
            iter: iter.into_iter(),
        }
    }
}

impl<T: Iterator<Item = i32>> Iterator for IntIterator<T> {
    type Item = i32;

    fn next(&mut self) -> Option<Self::Item> {
        self.iter.next()
    }
}

fn main() {
    let vec = vec![1, 2, 3];
    let int_iter: IntIterator<_> = vec.into_iter().collect();
    for i in int_iter {
        println!("{}", i);
    }
}

但它说“不匹配的类型”:

error[E0308]: mismatched types
  --> src/main.rs:10:19
   |
7  | impl<T: Iterator<Item = i32>> FromIterator<i32> for IntIterator<T> {
   |      - this type parameter
...
10 |             iter: iter.into_iter(),
   |                   ^^^^^^^^^^^^^^^^ expected type parameter `T`, found associated type
   |
   = note: expected type parameter `T`
             found associated type `<I as IntoIterator>::IntoIter`
   = note: you might be missing a type parameter or trait bound

error[E0282]: type annotations needed
  --> src/main.rs:25:52
   |
25 |     let int_iter: IntIterator<_> = vec.into_iter().collect();
   |                                                    ^^^^^^^ cannot infer type of the type parameter `B` declared on the associated function `collect`
   |
help: consider specifying the generic argument
   |
25 |     let int_iter: IntIterator<_> = vec.into_iter().collect::<IntIterator<_>>();
   |                                                           ++++++++++++++++++

【问题讨论】:

    标签: rust


    【解决方案1】:

    我认为这是不可能的。 from_iter()的返回类型需要依赖于它的泛型参数,但是返回类型是Self,在方法和它的泛型参数之前就已经定义好了。

    【讨论】:

      【解决方案2】:

      FromIterator 通常用于制作消耗迭代器的东西。实施From(playground)可能会更好。

      impl<T, I> From<T> for IntIterator<I>
      where
          T: IntoIterator<Item = i32, IntoIter = I>,
      {
          fn from(value: T) -> Self {
              IntIterator {
                  iter: value.into_iter(),
              }
          }
      }
      

      请注意,您不需要在Vec 上调用into_iter,因为您正在为IntoIterator 而不是Iterator 实现它。

      或者,您可以创建一个扩展特征(这次是在Iterator 上,但如果您希望在IntoIterator 上使用它,应该可以类似地工作)(playground)

      trait ToIntIter: Iterator<Item = i32> + Sized {
          fn to_int_iter(self) -> IntIterator<Self> {
              IntIterator {
                  iter: self
              }
          }
      }
      
      impl<T: Iterator<Item = i32>> ToIntIter for T {}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多