更高级别的生命周期和泛型不能很好地发挥作用

时间:2016-09-18 14:19:25

标签: rust closures traits lifetime

在这里的代码中

trait Foo {
    type Output;
    fn foo(self) -> Self::Output;
}

impl<'a> Foo for &'a () {
    type Output = &'a ();
    fn foo(self) -> Self::Output {
        self
    }
}

fn func<F: Foo>(f: F) -> F::Output {
    f.foo()
}

fn func2<'a>(f: &'a ()) -> &'a () {
    func::<&'a ()>(f)
}

fn has_hrl<F: Fn(&()) -> &()>(f: F) {}

fn main() {
    //has_hrl(func); // FAILS
    has_hrl(func2);
    has_hrl(|x| func(x));
}

我们想做has_hrl(func),但Rust只接受闭包has_hrl(|x| func(x))。这是为什么?因为它适用于func2中的具体类型,但不适用于泛型类型。

1 个答案:

答案 0 :(得分:7)

在这个表达式中:

has_hrl(func)

编译器被迫选择func的一个特定实例。 funcF: Foo上是通用的,对于所有'a&'a ()实现Foo,但编译器只能选择一个特定'a来实例化func,因为类型变量不能代表多种类型。因此,func::<&'a ()>未实现for<'a> Fn(&'a ()) -> &'a (),它仅针对特定生命周期Fn(&'x ()) -> &'x ()实施'x

  

如果您宣布has_hrlfn has_hrl<'a, F: Fn(&'a ()) -> &'a ()>(_: F) {},那么这将有效。但是,我的功率水平不足以解释为什么生命周期需要明确。 - ljedrz

那是因为原始声明具有隐含的更高排名的生命周期界限(界限等于F: for<'a> Fn(&'a ()) -> &'a ()),这意味着F必须为<{1}}实现<{1}} em>所有生命期Fn(&'a ()) -> &'a ()。您的版本只需要'a来实现F一个具体的生命周期。您还会发现,如果Fn(&'a ()) -> &'a ()尝试使用has_hrl函数本地的生命周期调用闭包,则此版本不起作用,因为调用者无法通过该生命周期作为参数(这就是为什么引入了更高级别的生命周期界限)。