当您编写泛型特征实现(如
impl<'a, 'b, Iterable, Item> Scan for Iterable
要求所有泛型类型都出现在实现特征的类型的定义中.在你的情况下,Iterable
在那里,而Item
不在那里.
但你并不真的需要Item
个才能成为通用的.我认为您添加它只是为了给它写一个约束.理想情况下,您希望编写如下内容:
impl<'a, 'b, Iterable> Scan for Iterable
where
&'b Iterable: IntoIterator<Item : Scan + 'a>,
不幸的是,这仍然是一个不稳定的功能associated_type_bounds
.
但幸运的是,您不需要与之绑定的关联类型.您可以改为这样写:
impl<'a, 'b, Iterable> Scan for Iterable
where
&'b Iterable: IntoIterator,
<&'b Iterable as IntoIterator>::Item : Scan + 'a,
现在约束起作用了,但是生命周期失败了!
error[E0309]: the parameter type `Iterable` may not live long enough
--> src/lib.rs:27:19
|
27 | &'b Iterable: IntoIterator,
| ^^^^^^^^^^^^ ...so that the reference type `&'b Iterable` does not outlive the data it points at
|
help: consider adding an explicit lifetime bound...
|
23 | impl<'a, 'b, Iterable: 'b> Scan for Iterable
| ++++
如果你按照编译器的建议go 做,加上Iterable: 'b
和...现在,如果函数本身的实现失败:
error: lifetime may not live long enough
--> src/lib.rs:31:21
|
23 | impl<'a, 'b, Iterable> Scan for Iterable
| -- lifetime `'b` defined here
...
29 | fn scan(&self, arena: &mut Arena)
| - let's call the lifetime of this reference `'1`
30 | {
31 | for item in (&self).into_iter() {
| ^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'b`
这实际上是意料之中的,因为匿名生存期&self
与'b
无关,并且您不能更改这一点,因为您不能向函数特征的实现添加约束.
解决这个问题的一个显而易见的解决方案(如果没有任何其他代码,它可能不适合您)是实现&'b Iterable
的特征.这样一来,&self
实际上是&&'b Iterable
,所有的东西都可以放在一起.此外,Iterable: 'b
现在是隐含的,不再需要:
impl<'a, 'b, Iterable> Scan for &'b Iterable
where
&'b Iterable: IntoIterator,
<&'b Iterable as IntoIterator>::Item : Scan + 'a,
{
fn scan(&self, arena: &mut Arena)
{
for item in self.into_iter() {
item.scan(arena);
}
}
}
顺便说一句,我认为'a
岁的生命周期 基本上是没用的.