[英]Type bound for a function with return lifetime
Consider the function考虑 function
fn f(v: &[usize]) -> impl Iterator<Item = usize> + '_ {
v.iter().cloned()
}
I want to write a generic function g
which accepts any function with the same signature as f
, and calls that function with various lifetimes.我想编写一个通用的 function
g
,它接受任何具有与f
相同签名的 function ,并调用具有不同生命周期的 function 。 Is this possible?这可能吗?
My attempt 1 : I naively wrote我的尝试1 :我天真地写了
fn g<F>(f: F)
where
F: for<'a> Fn(&'a [usize]) -> (impl Iterator<Item = usize> + 'a) {}
but I got但我得到了
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
My attempt 2 : I tried to give g
another type parameter for the specific iterator type:我的尝试 2 :我试图给
g
特定迭代器类型的另一个类型参数:
fn g<F, I>(f: F)
where
I: Iterator<Item = usize>,
F: for<'a> Fn(&'a [usize]) -> I {}
I think this would work if the iterator were 'static
.我认为如果迭代器是
'static
,这将起作用。 But in this case I'd need I
to be a higher kinded type with one lifetime parameter.但在这种情况下,
I
需要成为具有一个生命周期参数的更高种类的类型。 Concretely, this g
compiles but doesn't accept f
.具体来说,这个
g
编译但不接受f
。
My attempt 3 : As above, but giving g
a lifetime parameter to specialize f
:我的尝试 3 :如上所述,但给
g
一个生命周期参数来专门化f
:
fn g<'a, F, I>(f: F)
where
I: Iterator<Item = usize> + 'a,
F: Fn(&'a [usize]) -> I {}
This compiles and accepts f
, but the body of g
can only use f
with the specific lifetime 'a
.这编译并接受
f
,但g
的主体只能使用具有特定生命周期'a
f
。
As Sven Marnach pointed out it could be done with a Box
pointer.正如 Sven Marnach 指出的那样,它可以通过
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)
}
Based on this post , I found a solution for the original interface (without a Box
) using a helper trait:基于这篇文章,我找到了一个使用辅助特征的原始界面(没有
Box
)的解决方案:
fn f(v: &[usize]) -> impl Iterator<Item = usize> + '_ {
v.iter().cloned()
}
trait Helper<'a> {
type I: Iterator<Item = usize> + 'a;
fn call(self, v: &'a [usize]) -> Self::I;
}
impl<'a, I, F> Helper<'a> for F
where
I: Iterator<Item = usize> + 'a,
F: Fn(&'a [usize]) -> I,
{
type I = I;
fn call(self, v: &'a [usize]) -> Self::I {
self(v)
}
}
fn g<F>(f: F)
where
F: for<'a> Helper<'a>,
{
let v = vec![1, 2, 3];
{
let iter = f.call(&v);
for i in iter {
println!("{}", i);
}
}
}
pub fn main() {
g(f)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.