2016-04-09 46 views
2

我有以下struct为什么这个struct成员需要两个生命期?

struct PeekableRead<'a, R: Read> { 
    reader: &'a mut R, 
    peeked_octet: Option<u8>, 
} 

哪个rustc不喜欢:

…:27:1: 30:2 error: the parameter type `R` may not live long enough [E0309] 
…:27 struct PeekableRead<'a, R: Read> { 
…:28 reader: &'a mut R, 
…:29 peeked_octet: Option<u8>, 
…:30 } 
…:27:1: 30:2 help: run `rustc --explain E0309` to see a detailed explanation 
…:27:1: 30:2 help: consider adding an explicit lifetime bound `R: 'a`... 
…:27:1: 30:2 note: ...so that the reference type `&'a mut R` does not outlive the data it points at 
…:27 struct PeekableRead<'a, R: Read> { 
…:28 reader: &'a mut R, 
…:29 peeked_octet: Option<u8>, 
…:30 } 

如果我的寿命增加R,如,R: Read + 'a,它的工作原理。但是为什么?参考文献'a是否指定了生命期?一定不要reader: &'a mut R,在struct PeekableRead<'a>住只要结构本身,因而“足够长”?

奇怪的是,我似乎需要;如果我将'a添加到R并将其从参考中删除,我仍然会得到error: missing lifetime specifier。我获得成功编译的唯一方法是两种,但对我来说,它们似乎冗余地指定了相同的东西。

(另外,为什么rustc输出struct两次输出?第二个看起来像什么就做一个建议,但似乎是完全一样的我有什么...)

回答

2

Doesn't the 'a on the reference specify the lifetime?

它规定了参考的的生存期,但不指定值的生命周期。这也解释了你的意见,即

if I add 'a to R and remove it from the reference, I still get error: missing lifetime specifier.

对于结构是有效的,我们既需要:价值被指出仍必须活着,所以必须参考。 (虽然在逻辑上,第一个条件暗示了第二个条件,因为参考永远不会超过它指向的值)。

+1

您可以考虑struct PeekableRead “结构的外部可见API,而这些字段是实现细节。然而,这种动机不是一个通用规则,因为我们可以考虑结构的某些属性,这些属性没有像这样明确拼写出来(每个泛型参数和自动特征的方差)。 – bluss

0

引用上的生命周期参数指定了引用对象的寿命(即引用指向的对象)。该对象可能是一个引用,也可能是一个包含一个或多个引用的复杂对象。然而,当你使用一个特质时,这些参考背后的对象的生命期是隐藏的(特质本身并不知道这些生命期);生命周期是编译器能够正确理解这些生命周期的原因。

当您在引用后面使用泛型类型时,需要添加一个边界以确保该类型的实例不包含比对那些实例的引用更短的引用。界限不是基于你如何使用类型而隐式添加的:界限不应该根据结构中的字段和你定义的类型的细节来改变。

例如,类型&'f File(对于每个'f)实施Read。我们可以使用该类型实例化PeekableRead:这给了我们一个PeekableRead<&'f File>PeekableRead<&'f File>存储对&'f File的可变引用,因此reader字段的具体类型为&'a mut &'f File。为使此参考有效,'a必须短于或等于'f。如果'f短于'a,那么您可以将&'f File替换为在引用被删除之前将被丢弃的那个,从而导致悬挂指针。当您添加绑定到R'a(即,当你写R: Read + 'a),你说“实例R必须超过'a”(即R可能不包含短于'a的引用)。

相关问题