在结构体字段中使用引用时是否有任何限制?

hoc*_*hej 5 struct lifetime rust

我试图了解 Rust 的生命周期如何影响结构。附件是一个让我困惑的最小例子。

我想给一个结构体一个对象的引用,然后需要更改这个对象。由于借用对象时无法更改该对象,因此我认为必须在更改对象时删除引用。所以我的想法是将变量定义为一个选项,并在修改对象期间通过将其设置为 来删除引用None。对于不使用结构的示例,这似乎可行。但是,如果我现在将此引用放入结构中,它将不起作用。在我看来,借用检查器忽略了变量string不再被借用的事实。有没有办法仍然通过结构实现所需的行为?

这有效(链接到游乐场):

fn main() {
    let mut string = "mutable string".to_string();
    let mut ref_to_string: Option<&str> = Some(&string);
    ref_to_string = None;
    string = "mutated string".to_string();
    ref_to_string = Some(&string);
}
Run Code Online (Sandbox Code Playgroud)

但是,这不起作用链接到游乐场

struct Foo<'a> {
    pub ref_data: Option<&'a str>,
}

fn main() {
    let mut string = "mutable string".to_string();
    let mut foo = Foo{ref_data: Some(&string)};
    foo.ref_data = None;
    string = "mutated string".to_string();
    foo.ref_data = Some(&string);
}

Run Code Online (Sandbox Code Playgroud)

错误信息:

error[E0506]: cannot assign to `string` because it is borrowed
  --> src/main.rs:11:5
   |
9  |     let mut foo = Foo{ref_data: Some(&string)};
   |                                      ------- borrow of `string` occurs here
10 |     foo.ref_data = None;
11 |     string = "mutated string".to_string();
   |     ^^^^^^ assignment to borrowed `string` occurs here
12 |     foo.ref_data = Some(&string);
   |     ---------------------------- borrow later used here

For more information about this error, try `rustc --explain E0506`.
Run Code Online (Sandbox Code Playgroud)

Net*_*ave 2

问题是您string两次引用该变量。借用时,第一个约束&str生命周期至少为 foo。引用“另一个”变量中的另一个字符串应该没有问题:

fn main() {
    let string = "mutable string".to_string();
    let mut foo = Foo {
        ref_data: Some(&string),
    };
    foo.ref_data = None;

    let string = "mutated string".to_string();
    foo.ref_data = Some(&string);
}

Run Code Online (Sandbox Code Playgroud)

操场

请注意使用另一个let绑定而不是改变变量。