如何递归地传递函数指针



我想写一个Iterator适配器,它递归地将函数应用于其底层Iterator。递归地,因为变量IR::Loop包括一个Vec<IR>,其中的迭代器也应该传递给函数。

函数应该取一个&mut Iterator<Item = IR>,并使用它来计算迭代器的下一个值(如itertools::batching)。

use std::iter::Peekable;
#[derive(Clone)]
enum IR {
    OperationA,
    OperationB,
    Loop(Vec<IR>),
}
pub trait MyItertools: Iterator {
    fn apply_recursive<F: Fn(&mut Peekable<Self>) -> Option<Self::Item>>(
        self,
        f: F,
    ) -> ApplyRecursive<Self, F>
    where
        Self: Sized,
        Self::Item: Clone,
    {
        ApplyRecursive {
            iter: self.peekable(),
            f: f,
        }
    }
}
impl<T: ?Sized> MyItertools for T
where
    T: Iterator,
{
}
//applies a function recursively to some Iterator with Item=IR
#[derive(Clone)]
struct ApplyRecursive<I, F>
where
    I: Iterator,
    I::Item: Clone,
{
    iter: Peekable<I>,
    f: F,
}
impl<I: Iterator<Item = IR>, F> Iterator for ApplyRecursive<I, F>
where
    F: Fn(&mut Peekable<I>)
       -> Option<I::Item>,
{
    type Item = I::Item;
    fn next(&mut self) -> Option<I::Item> {
        match self.iter.peek() {
            Some(&IR::Loop(code)) => {
                self.iter.next(); //advance the iterator
                let code: Vec<IR> = code.into_iter().apply_recursive(self.f).collect();
                Some(IR::Loop(code))
            }
            Some(x) => (self.f)(&mut self.iter),
            None => None,
        }
    }
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}
fn main() {}

操场

我做错了什么?我甚至不明白错误信息:

error[E0277]: the trait bound `for<'r> F: std::ops::Fn<(&'r mut std::iter::Peekable<std::vec::IntoIter<IR>>,)>` is not satisfied
  --> src/main.rs:54:54
   |
54 |                 let code: Vec<IR> = code.into_iter().apply_recursive(self.f).collect();
   |                                                      ^^^^^^^^^^^^^^^ the trait `for<'r> std::ops::Fn<(&'r mut std::iter::Peekable<std::vec::IntoIter<IR>>,)>` is not implemented for `F`
   |
   = help: consider adding a `where for<'r> F: std::ops::Fn<(&'r mut std::iter::Peekable<std::vec::IntoIter<IR>>,)>` bound
error[E0277]: the trait bound `for<'r> F: std::ops::FnOnce<(&'r mut std::iter::Peekable<std::vec::IntoIter<IR>>,)>` is not satisfied
  --> src/main.rs:54:54
   |
54 |                 let code: Vec<IR> = code.into_iter().apply_recursive(self.f).collect();
   |                                                      ^^^^^^^^^^^^^^^ the trait `for<'r> std::ops::FnOnce<(&'r mut std::iter::Peekable<std::vec::IntoIter<IR>>,)>` is not implemented for `F`
   |
   = help: consider adding a `where for<'r> F: std::ops::FnOnce<(&'r mut std::iter::Peekable<std::vec::IntoIter<IR>>,)>` bound
error: no method named `collect` found for type `ApplyRecursive<std::vec::IntoIter<IR>, F>` in the current scope
  --> src/main.rs:54:78
   |
54 |                 let code: Vec<IR> = code.into_iter().apply_recursive(self.f).collect();
   |                                                                              ^^^^^^^
   |
   = note: the method `collect` exists but the following trait bounds were not satisfied: `F : std::ops::Fn<(&mut std::iter::Peekable<std::vec::IntoIter<IR>>,)>`, `ApplyRecursive<std::vec::IntoIter<IR>, F> : std::iter::Iterator`
   = help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `collect`, perhaps you need to implement it:
   = help: candidate #1: `std::iter::Iterator`

最后一个错误表示您没有IteratorIterator仅在特定条件下为您的结构实现,并且您不满足这些条件。第二个错误解释了原因。

特征CCD_ 9不是针对类型CCD_

那么,为什么编译器认为这不起作用呢?让我们看看您的限制:

impl<I, F> Iterator for ApplyRecursive<I, F>
where
    I: Iterator<Item = IR>
    F: Fn(&mut Peekable<I>) -> Option<I::Item>,

此结构引用了实现Iterator具体类型I。那么F是一个具体类型,它接受对与I相同的具体类型的可变引用。然而,您尝试在具体类型IntoIter上使用您的函数(专门用于任何类型),但这可能是一个不同的具体类型!

最简单的修复方法是删除这里的泛型:

impl<F> Iterator for ApplyRecursive<vec::IntoIter<IR>, F>
where
    F: Fn(&mut vec::IntoIter<IR>) -> Option<IR>,
{
    type Item = IR;
    fn next(&mut self) -> Option<IR> {

这解开了关于可变性、访问私有字段和导出私有类型的其他一系列错误,但我认为它克服了这个困难。

或者,我们可以更改F以接受特征对象,而不必担心专门化它:

pub trait CustomIter: Iterator {
    fn apply_recursive<F>(self, f: F) -> ApplyRecursive<Self, F>
    where
        F: Fn(&mut Iterator<Item = Self::Item>) -> Option<Self::Item>,
        Self: Sized,
        Self::Item: Clone,
    {
        ApplyRecursive { iter: self.peekable(), f: f }
    }
}
impl<I, F> Iterator for ApplyRecursive<I, F>
where
    I: Iterator<Item = IR>,
    F: Fn(&mut Iterator<Item = IR>) -> Option<IR>,
{
    type Item = I::Item;
    fn next(&mut self) -> Option<IR> {

最新更新