我在一些博客文章中发现了以下特质定义。
trait HasIter<'a, _Dummy=&'a Self, _Item = &'a <Self as IntoIterator>::Item>: IntoIterator
{
type Iter: Iterator<Item = _Item>;
}
我尝试了一下,并决定在Iter的声明中替换_type,如下所示:
trait HasIter<'a, _Dummy=&'a Self>: IntoIterator
{
type Iter: Iterator<Item = &'a <Self as IntoIterator>::Item>;
}
我一这么做,编译器就会抱怨
the associated type `<Self as IntoIterator>::Item` may not live long enough
我想我错过了Rust中的一些生命周期概念。这里到底有什么区别呢?既然我们在两种情况下都附加了相同的生命周期'a,为什么我们不大声地这样做呢?
1条答案
按热度按时间os8fio9y1#
在第二个例子中,你有
&'a <Self as IntoIterator>::Item
,但是如果<Self as IntoIterator>::Item
引用的类型包含的引用没有'a
那么长怎么办?引用的有效期不能超过它指向的数据。编译器告诉你如何解决这个问题:果然,这编译:
在第一个例子中没有得到相同错误的原因是因为
_Item = &'a <Self as IntoIterator>::Item
指定了一个泛型类型,并将提供的类型 * 作为默认值。* 默认值并不一定在所有情况下都有意义,因为如果<Self as IntoIterator>::Item: 'a
不为true,它可以在实现HasIter
的站点被拒绝。相反,第二个例子中的Iter
上的界限必须对trait的 * 所有可能的实现 * 保持。