考虑功能

fn f(v: &[usize]) -> impl Iterator<Item = usize> + '_ {
    v.iter().cloned()
}

我想编写一个泛型函数g,它接受与f具有相同签名的任何函数,并用不同的生命周期调用该函数.这可能吗?


My attempt 1:我天真地写道

fn g<F>(f: F)
where
    F: for<'a> Fn(&'a [usize]) -> (impl Iterator<Item = usize> + 'a) {}

但我得到了

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return

My attempt 2:我try 为特定迭代器类型提供g个其他类型参数:

fn g<F, I>(f: F)
where
    I: Iterator<Item = usize>,
    F: for<'a> Fn(&'a [usize]) -> I {}

我认为,如果迭代器是'static,这将起作用.但在这种情况下,我需要I是一种更高类型的类型,具有一个生存期参数.具体来说,这g编译,但不接受f.


My attempt 3:如上所述,但给g一个生存期参数来专门化f:

fn g<'a, F, I>(f: F)
where
    I: Iterator<Item = usize> + 'a,
    F: Fn(&'a [usize]) -> I {}

这编译并接受f,但g的主体只能使用具有特定生存期'af.

推荐答案

正如斯文·马纳奇指出的那样,这可以用Box分完成.

fn f(v: &[usize]) -> Box<dyn Iterator<Item = usize> + '_> {
    Box::new(v.iter().cloned())
}

fn g<F>(f: F)
where
    F: Fn(&[usize]) -> Box<dyn Iterator<Item = usize> + '_>
{
    let v = vec![1, 2, 3];
    {
        let iter = f(&v);
        for i in iter {
            println!("{}", i);
        }
    }
}

fn main() {
    g(f)
}

Rust相关问答推荐

将内部类型作为参数的泛型 struct 上的方法

为什么BitVec缺少Serialize trait?

支持TLS的模拟HTTP服务器

无法将记录器向下转换回原始 struct

在析构赋值中使用一些现有绑定

当对VEC;U8>;使用serde_json时,Base64编码是保护空间的好方法吗?

完全匹配包含大小写的整数范围(&Q;)

无法实现整型类型的泛型FN

我们能确定Rust会优化掉Clone()吗?如果它会立即掉落?

如何将一个矩阵的列分配给另一个矩阵,纳尔代数?

为什么切片时需要参考?

如何从borrow 的异步代码运行阻塞代码?

unwrap 选项类型出现错误:无法移出共享引用后面的*foo

方法可以被误认为是标准特性方法

pyO3 和 Panics

在 Bevy 项目中为 TextureAtlas 精灵实施 NearestNeighbor 的正确方法是什么?

在 Rust 中,将可变引用传递给函数的机制是什么?

如何在 Rust 中返回通用 struct

将 (T, ()) 转换为 T 安全吗?

为什么 Bevy 的 Trait 边界不满足 Rapier 物理插件?