说我们有一些像这样的代码:
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
。事实证明,bar
对self.stack
起到了某些作用,因此我们很难在Foo
上实现通用定义。
该代码无法编译,抱怨Stack
和&X
的生存期不同。 Playground link。
我们如何使这些寿命匹配?
答案 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
。
完整代码:
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(){}