我有以下两种类型:
struct A {
x: int
}
struct B<'a> {
y: &'a A
}
我想创建一个创建A类对象的函数和一个B类对象,该对象包含对A类对象的引用,并返回B类型的对象:
fn bar<'a>() -> B<'a> {
let y = A { x: 3 };
B { y: &y }
}
但是我收到以下编译器错误:
main.rs:11:13: 11:14 error: `y` does not live long enough
main.rs:11 B { y: &y }
^
main.rs:9:23: 12:2 note: reference must be valid for the lifetime 'a as defined on the block at 9:22...
main.rs:9 fn bar<'a>() -> B<'a> {
main.rs:10 let y = A { x: 3 };
main.rs:11 B { y: &y }
main.rs:12 }
main.rs:9:23: 12:2 note: ...but borrowed value is only valid for the block at 9:22
main.rs:9 fn bar<'a>() -> B<'a> {
main.rs:10 let y = A { x: 3 };
main.rs:11 B { y: &y }
main.rs:12 }
error: aborting due to previous error
这个错误似乎是合理的,因为我无法找到解决问题的方法。有没有办法指定y
的生命周期至少应为'a
,而不更改A
或B
的定义?
答案 0 :(得分:3)
无法指定y
生命周期至少应为'a
,因为这是不可能的:y
是一个局部变量,只是不能比它在中创建的堆栈帧寿命更长。
一般情况下,如果您发现需要这样做,实际上您很可能希望B
拥有A
:
struct B { y: A }
在这种情况下,代码变得微不足道:
fn bar() -> B {
let y = A { x: 3 }
B { y: y }
}
你可以从另一点看这个。这是您想要的bar()
签名:
fn bar<'b>() -> B<'b> { ... }
'b
是一个生命周期参数,也就是说,它可以由此函数的调用者任意选择。但是没有什么可以阻止调用者替换'static
'b
:
let x: B<'static> = bar();
但是,只有当bar()
始终返回B<'static>
时才会出现这种情况,这似乎不是您想要的。事实上,上述签名与此完全相同:
fn bar() -> B<'static> { ... }