"X does not live long enough" 在嵌套范围内覆盖结构字段(与其他字段具有相同的生命周期)时出错
"X does not live long enough" error when overriding struct field (that has the same lifetime as other fields) inside nested scope
我实现了一个结构,其中我为所有引用字段提供了相同的生命周期。当我覆盖内部范围内的字段时,生命周期似乎不起作用。我得到一个错误:
error[E0597]: str2
does not live long enough
这是我的代码:
struct Test<'a> {
a: Option<&'a String>,
b: Option<&'a String>,
}
impl<'a> Test<'a> {
pub fn new(a: Option<&'a String>) -> Self {
Self {
a,
b: None,
}
}
}
fn main () {
let str1 = String::from("test1");
let mut test = Test::new(Some(&str1));
{
let str2 = String::from("test2");
test.b = Some(&str2);
}
println!("{:?} and {:?}", test.a, test.b);
}
这是minimal sandbox implementation。
你能解释一下如何强制引用在定义的生命周期内工作吗?为什么在这种情况下代码无法编译?
我想你误会了。
带有生命周期注解的引用不会保持值存活,它们只是指定它们必须存活多久才能被存储在结构中。
引用不会取得变量的所有权。生命周期只是确保拥有该变量的人不会在 'a
结束之前销毁它。
编译器会自动计算出 'a
必须是什么。在您的情况下,最近使用的点 test.a
和 test.b
是 println!(...)
。因此,编译器确定 test
对象的 'a
的生命周期必须至少到 println!(...)
.
然后,编译器意识到 b
的所有者 str2
在 }
的末尾被丢弃,这与生命周期 [=11] 不匹配=] 的 test
对象,因为它没有到达 println!(...)
.
如果你通过运行cargo check
、cargo build
或cargo run
查看更详细的cargo错误信息,你可以看到:
error[E0597]: `str2` does not live long enough
--> src/main.rs:17:23
|
17 | test.b = Some(&str2);
| ^^^^^ borrowed value does not live long enough
18 | }
| - `str2` dropped here while still borrowed
19 |
20 | println!("{:?} and {:?}", test.a, test.b);
| ------ borrow later used here
我实现了一个结构,其中我为所有引用字段提供了相同的生命周期。当我覆盖内部范围内的字段时,生命周期似乎不起作用。我得到一个错误:
error[E0597]:
str2
does not live long enough
这是我的代码:
struct Test<'a> {
a: Option<&'a String>,
b: Option<&'a String>,
}
impl<'a> Test<'a> {
pub fn new(a: Option<&'a String>) -> Self {
Self {
a,
b: None,
}
}
}
fn main () {
let str1 = String::from("test1");
let mut test = Test::new(Some(&str1));
{
let str2 = String::from("test2");
test.b = Some(&str2);
}
println!("{:?} and {:?}", test.a, test.b);
}
这是minimal sandbox implementation。
你能解释一下如何强制引用在定义的生命周期内工作吗?为什么在这种情况下代码无法编译?
我想你误会了。
带有生命周期注解的引用不会保持值存活,它们只是指定它们必须存活多久才能被存储在结构中。
引用不会取得变量的所有权。生命周期只是确保拥有该变量的人不会在 'a
结束之前销毁它。
编译器会自动计算出 'a
必须是什么。在您的情况下,最近使用的点 test.a
和 test.b
是 println!(...)
。因此,编译器确定 test
对象的 'a
的生命周期必须至少到 println!(...)
.
然后,编译器意识到 b
的所有者 str2
在 }
的末尾被丢弃,这与生命周期 [=11] 不匹配=] 的 test
对象,因为它没有到达 println!(...)
.
如果你通过运行cargo check
、cargo build
或cargo run
查看更详细的cargo错误信息,你可以看到:
error[E0597]: `str2` does not live long enough
--> src/main.rs:17:23
|
17 | test.b = Some(&str2);
| ^^^^^ borrowed value does not live long enough
18 | }
| - `str2` dropped here while still borrowed
19 |
20 | println!("{:?} and {:?}", test.a, test.b);
| ------ borrow later used here