How does for<> syntax differ from a regular lifetime bound?
考虑以下代码:
1 2 3 4 | trait Trait< T > {} fn foo<'a>(_b: Box<dyn Trait<&'a usize>>) {} fn bar(_b: Box<dyn for<'a> Trait<&'a usize>>) {} |
函数
另外,在什么情况下我需要上述的
简而言之,
但是,在这种特殊情况下,当
1 2 3 | trait Trait< T > { fn do_something(&self, value: T); } |
请记住,生存期参数与通用类型参数非常相似。使用泛型函数时,始终指定其所有类型参数,并提供具体类型,然后编译器使函数单一化。生命周期参数也是如此:当调用具有生命周期参数的函数时,尽管隐式指定了生命周期,但也可以:
1 2 3 4 5 6 7 | // imaginary explicit syntax // also assume that there is TraitImpl::new::< T >() -> TraitImpl< T >, // and TraitImpl< T >: Trait< T > 'a: { foo::<'a>(Box::new(TraitImpl::new::<&'a usize>())); } |
现在,
1 2 3 4 | fn foo<'a>(b: Box<Trait<&'a usize>>) { let x: usize = 10; b.do_something(&x); } |
这不会编译,因为局部变量的生命周期严格小于生命周期参数指定的生命周期(我清楚这是为什么),因此您无法调用
但是,您可以使用
1 2 3 4 | fn bar(b: Box<for<'a> Trait<&'a usize>>) { let x: usize = 10; b.do_something(&x); } |
之所以有效,是因为现在
当您使用接受引用的闭包时,这确实很重要。例如,假设您要在
1 2 3 4 5 6 7 8 | impl< T > Option< T > { fn filter<F>(self, f: F) -> Option< T > where F: FnOnce(&T) -> bool { match self { Some(value) => if f(&value) { Some(value) } else { None } None => None } } } |
这里的闭包必须接受对
但是
1 | fn filter<'a, F>(self, f: F) -> Option< T > where F: FnOnce(&'a T) -> bool |
但是,这行不通。与上面的
另一方面,如果我们像这样扩展
1 | fn filter<F>(self, f: F) -> Option< T > where F: for<'a> FnOnce(&'a T) -> bool |
然后使用
您还可以在Nomicon中阅读有关HRTB的另一种解释。