"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.atest.bprintln!(...)。因此,编译器确定 test 对象的 'a 的生命周期必须至少到 println!(...).

然后,编译器意识到 b 的所有者 str2} 的末尾被丢弃,这与生命周期 [=11] 不匹配=] 的 test 对象,因为它没有到达 println!(...).

如果你通过运行cargo checkcargo buildcargo 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