更高等级的生命周期和泛型表现不佳

Higher rank lifetimes and generics not playing nicely

在此处的代码中

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 中的具体类型,但不适用于泛型类型。

在这个表达式中:

has_hrl(func)

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

内实现 Fn(&'x ()) -> &'x ()

This would work if you declared has_hrl like fn has_hrl<'a, F: Fn(&'a ()) -> &'a ()>(_: F) {}. My power level is insufficient to explain why the lifetime needs to be explicit, though. – ljedrz

那是因为原始声明有一个隐含的更高级别的生命周期边界(该边界等同于 F: for<'a> Fn(&'a ()) -> &'a ()),这意味着 F 必须为 [=40 实现 Fn(&'a ()) -> &'a () =]全部 生命周期'a。您的版本只需要 F 来实现 Fn(&'a ()) -> &'a () 一个具体的生命周期。您还会发现,如果 has_hrl 尝试使用 has_hrl 函数的本地生命周期调用闭包,则此版本不起作用,因为调用者不可能将该生命周期作为参数传递(这就是引入更高级别生命周期界限的原因。