如何使这些寿命匹配?

时间:2019-06-22 15:03:48

标签: rust lifetime

说我们有一些像这样的代码:

struct X {
    y: String,
}

trait Foo {
    fn bar(&mut self, x: &X);
}

type Stack<'a> = Vec<&'a X>;

struct Quux<'a> {
    stack: Stack<'a>,
}

fn bar(stack: &mut Stack, x: &X) {
    stack.push(x);
}

impl <'a>Foo for Quux<'a> {
    fn bar(&mut self, x: &X) {
        bar(&mut self.stack, x)
    }
}

目标是在实现bar的结构之间共享功能Foo。事实证明,barself.stack起到了某些作用,因此我们很难在Foo上实现通用定义。

该代码无法编译,抱怨Stack&X的生存期不同。 Playground link

我们如何使这些寿命匹配?

1 个答案:

答案 0 :(得分:1)

答案实际上是在问题中。您需要使寿命匹配。因此,您的(非特征)bar必须具有签名

fn bar<'a>(stack: &mut Stack<'a>, x: &'a X)

现在,您的性格太笼统了。它在保证它不能兑现。它说:“如果某个东西实现了Foo,那么您可以使用对bar any 引用调用X”。但这不是您想要的。您需要将其生命周期限制为x。因此,我们将其参数化。

trait Foo<'a> {
    fn bar(&mut self, x: &'a X);
}

然后我们更改impl

impl <'a>Foo<'a> for Quux<'a> {
    fn bar(&mut self, x: &'a X) {
        bar(&mut self.stack, x)
    }
}

因为现在我们做出正确的保证。 Quux<'a>未实现Foo。在特定的生存期Foo<'a>中,它专门实现了'a

Playground link

完整代码:

struct X {
    y: String,
}

trait Foo<'a> {
    fn bar(&mut self, x: &'a X);
}

type Stack<'a> = Vec<&'a X>;

struct Quux<'a> {
    stack: Stack<'a>,
}

fn bar<'a>(stack: &mut Stack<'a>, x: &'a X) {
    stack.push(x);
}

impl <'a>Foo<'a> for Quux<'a> {
    fn bar(&mut self, x: &'a X) {
        bar(&mut self.stack, x)
    }
}

fn main(){}