[英]Rust lifetime error expected concrete lifetime but found bound lifetime
I am having an issue working with lifetime parameters for structs. 我在使用结构的生命周期参数时遇到问题。 I am not 100% sure how to describe the problem, but I created a trivial case that shows my compile time error.
我不是100%肯定如何描述问题,但我创建了一个显示我的编译时错误的简单案例。
struct Ref;
struct Container<'a> {
r : &'a Ref
}
struct ContainerB<'a> {
c : Container<'a>
}
trait ToC {
fn to_c<'a>(&self, r : &'a Ref) -> Container<'a>;
}
impl<'a> ToC for ContainerB<'a> {
fn to_c(&self, r : &'a Ref) -> Container<'a> {
self.c
}
}
The error I am getting with this is 我得到的错误是
test.rs:16:3: 18:4 error: method `to_c` has an incompatible type for trait: expected concrete lifetime, but found bound lifetime parameter 'a
test.rs:16 fn to_c(&self, r : &'a Ref) -> Container<'a> {
test.rs:17 self.c
test.rs:18 }
test.rs:16:48: 18:4 note: expected concrete lifetime is the lifetime 'a as defined on the block at 16:47
test.rs:16 fn to_c(&self, r : &'a Ref) -> Container<'a> {
test.rs:17 self.c
test.rs:18 }
error: aborting due to previous error
I have tried many variations and just can't get this thing to compile. 我已经尝试了很多变化,只是无法编译这个东西。 I found another post here ( How to fix: expected concrete lifetime, but found bound lifetime parameter ) but is appears to get around the problem instead of solving it.
我在这里找到了另一篇文章( 如何修复:预期的具体生命周期,但找到了绑定生命周期参数 )但似乎解决了问题而不是解决问题。 I can't really see why the problem even originates.
我真的不明白为什么问题甚至起源。 The &Ref is being passed along via moves so it should just work right?
&Ref正在通过移动传递,所以它应该正常工作?
Any ideas? 有任何想法吗? Thanks for all the help.
谢谢你的帮助。
Let's compare the two definitions. 让我们比较两个定义。 First, the trait method:
一,特质方法:
fn to_c<'a>(&self, r: &'a Ref) -> Container<'a>;
And the implementation: 并实施:
fn to_c(&self, r: &'a Ref) -> Container<'a>;
See the difference? 看到不同? The latter doesn't have
<'a>
. 后者没有
<'a>
。 <'a>
has been specified elsewhere; 其他地方已指明
<'a>
; the fact that it has the same name does not matter: it is a different thing entirely. 它具有相同名称的事实并不重要:它完全是另一回事。
Functionally, your trait definition says that the returned container will have a reference inside it to something from r
, but nothing from self
. 从功能上讲,你的特征定义表明返回的容器里面会有一个来自
r
的引用,但是没有来自self
。 It may use self
inside the method, but it may not store any references to it in the returned value. 它可以在方法中使用
self
,但它可能不会在返回的值中存储对它的任何引用。
Your method definition, however, is using a 'a
that ties the lifetimes of r
and the returned Container
to self
(that is, to the object itself, not the reference—the ρ₂ in &'ρ₁ T<'ρ₂>
—it's a subtle but sometimes significant difference), whereas the trait definition had no such connection. 您的方法定义,然而,使用
'a
是关系的寿命r
和返回的Container
到self
(即,对象本身,而不是基准的ρ₂在&'ρ₁ T<'ρ₂>
-它是一个细微但有时显着的差异),而特质定义没有这种联系。
The two can be made to match by inserting the <'a>
in the method definition in the implementation. 通过在实现中的方法定义中插入
<'a>
,可以使两者匹配。 But bear in mind that that is shadowing the 'a
from ContainerB<'a>
; 但请记住,这是影响
'a
从ContainerB<'a>
; it is not the same 'a
! 它不一样
'a
! We're better to give it another name; 我们最好给它另一个名字; for convenience, I'll make the change the other way round, changing it on the impl instead of the method (either would do):
为方便起见,我将进行相反的更改,在impl而不是方法上更改它(要么会这样做):
impl<'b> ToC for ContainerB<'b> {
fn to_c<'a>(&self, r: &'a Ref) -> Container<'a> {
self.c
}
}
But now of course you have a problem: the return value is of type Container<'b>
(because that's what the field c
in a ContainerB<'b>
is), but your signature demands Container<'a>
(something using a reference from r
, not from self
). 但是现在你有一个问题:返回值的类型为
Container<'b>
(因为这就是ContainerB<'b>
的字段c
是什么),但是你的签名需要Container<'a>
(使用的是r
引用,而不是来自self
)。
One way which would fix it is specifying the lifetime of &self
as 'a
in both the trait definition and the implementation; 解决这个问题的一种方法是将
&self
的生命周期指定为特征定义和实现中的'a
; in the implementation, this would then demand that 'b
was greater than or equal to 'a
(by virtue of the fact that you have successfully taken a reference with lifetime 'a
to an object with lifetime 'b
, and the object must outlive the reference) and so due to the subtyping ( 'a
is a subtype of 'b
) Container<'b>
would be safely coerced to Container<'a>
. 在实现中,这将要求
'b
大于或等于'a
(由于您已经成功地将具有生命周期'a
的引用引用到具有生命周期'b
的对象,并且该对象必须比由于子类型( 'a
是'b
的子类型), Container<'b>
将被安全地强制转换为Container<'a>
。
These sorts of lifetime matters are difficult to think about when you're not familiar with them; 当你不熟悉它们时,很难想到这些生活中的问题; but in time they become quite natural.
但随着时间的推移,它们变得很自然
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.