锈蚀寿命错误预期混凝土寿命,但发现束缚寿命 [英] Rust lifetime error expected concrete lifetime but found bound lifetime

查看:80
本文介绍了锈蚀寿命错误预期混凝土寿命,但发现束缚寿命的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用结构的生存期参数时遇到问题.我不是100%不确定如何描述问题,但是我创建了一个琐碎的案例来显示我的编译时错误.

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.

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
  }
}

我遇到的错误是

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

我尝试了许多变体,只是无法编译此东西.我在这里找到了另一篇文章(如何解决:预期的混凝土寿命,但找到了约束寿命参数),但似乎可以解决问题而不是解决问题.我真的不明白为什么这个问题甚至是由来的. & Ref正在通过移动传递,因此它应该可以正常工作吗?

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?

有什么想法吗?感谢您的所有帮助.

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>;

执行:

fn to_c(&self, r: &'a Ref) -> Container<'a>;

看到区别了吗?后者没有<'a>. <'a>已在其他位置指定;它具有相同名称的事实并不重要:完全是另一回事.

See the difference? The latter doesn’t have <'a>. <'a> has been specified elsewhere; the fact that it has the same name does not matter: it is a different thing entirely.

从功能上讲,您的特征定义表明返回的容器将在其中引用r中的内容,而则没有self 中的内容.它可以在方法内部使用self,但可能不会在返回值中存储对其的任何引用.

Functionally, your trait definition says that the returned container will have a reference inside it to something from r, but nothing from self. It may use self inside the method, but it may not store any references to it in the returned value.

但是,您的方法定义使用的是'a,它将r的生存期和返回的Container的生存期与self联系起来(即,对象本身,而不是引用- &'ρ₁ T<'ρ₂>-这是一个细微但有时很重要的差异),而特征定义则没有这种联系.

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>来使两者匹配.但是请记住,这正在从ContainerB<'a>遮盖'a是同一'a!我们最好给它起个名字;为了方便起见,我将进行另一种更改,在impl而不是方法上进行更改(两者都可以):

The two can be made to match by inserting the <'a> in the method definition in the implementation. But bear in mind that that is shadowing the 'a from ContainerB<'a>; it is not the same '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<'b> ToC for ContainerB<'b> {
    fn to_c<'a>(&self, r: &'a Ref) -> Container<'a> {
        self.c
    }
}

但是现在您当然遇到了一个问题:返回值的类型为Container<'b>(因为这就是ContainerB<'b>中的字段c的含义),但是您的签名需要Container<'a>(使用引用的东西)来自r,而不是来自self).

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).

一种解决它的方法是在特征定义和实现中将&self的生存期指定为'a.在实现中,这将要求'b大于或等于'a(由于您已经成功地引用了具有生存期'a的对象到具有生存期'b的对象,并且对象必须超过引用的寿命),因此由于子类型('a'b的子类型),Container<'b>将被安全地强制为Container<'a>.

One way which would fix it is specifying the lifetime of &self as 'a in both the trait definition and the implementation; 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>.

当您不熟悉这些类型的终生问题时,您将很难想到这些问题;但随着时间的流逝,它们变得很自然.

These sorts of lifetime matters are difficult to think about when you’re not familiar with them; but in time they become quite natural.

这篇关于锈蚀寿命错误预期混凝土寿命,但发现束缚寿命的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆