【问题标题】:What is the rule of mutable referencing inner values from mutable references?从可变引用中引用内部值的可变规则是什么?
【发布时间】:2021-11-20 17:21:57
【问题描述】:

从可变引用可变引用内部值的规则是什么?

这行得通:

#[derive(Debug)]
struct Outer {
    name: String,
    inner: Inner,
}

#[derive(Debug)]
struct Inner {
    val: String,
}

fn main() {
    let mut test = Outer {
        inner: Inner {
            val: String::from("test"),
        },
        name: String::from("name"),
    };
    let outer = &mut test;
    let inner = &mut outer.inner;
    *inner = Inner {
        val: String::from("x"),
    };
    outer.inner.val.push('b');
    println!("{:?}", outer); // Outer { name: "name", inner: Inner { val: "xb" } }
}

这失败了:

fn main() {
    let mut test = Outer {
        inner: Inner {
            val: String::from("test"),
        },
        name: String::from("name"),
    };
    let outer = &mut test;
    let inner = &mut test.inner; // note this time I'm using test instead of outer
    *inner = Inner {
        val: String::from("x"),
    };
    outer.inner.val.push('b');
    println!("{:?}", outer);
}

与:

error[E0499]: cannot borrow `test.inner` as mutable more than once at a time
  --> src/main.rs:20:17
   |
19 |     let outer = &mut test;
   |                 --------- first mutable borrow occurs here
20 |     let inner = &mut test.inner; // note this time I'm using test instead of outer
   |                 ^^^^^^^^^^^^^^^ second mutable borrow occurs here
...
24 |     outer.inner.val.push('b');
   |     --------------- first borrow later used here

【问题讨论】:

  • 一般来说,您要么使用test.inner = Inner{...}而不创建新借用,要么在创建新借用之前释放旧借用{ let outer = &mut test; ...; /*outer is destroyed*/ } { let inner = &mut test.inner; ... }
  • 您可以使用现有的引用来引用它内部的值 - 这不算作别名。但是,当内部引用处于活动状态时,它将使外部引用不可用。例如,如果您在第一个示例中交换 *inner = ...outer.inner.val.push 行,它将停止编译。总之,你不能有别名,但你可以有可变引用的嵌套

标签: rust borrow-checker


【解决方案1】:

Rust book 中解释了一切。

可变性的规则是(根据我的记忆写的):

  • 你可以修改一个变量的内容,如果它拥有它的内容,并且没有被借用

  • 一个变量一次只能有一个可变引用,并且只有可变引用才能读取或编辑变量的内容

您的第一个代码可以编译,因为 inner 借用了尚未被借用的 outer,从而使 outerinner 的生命周期内无法使用。

然而,在第二个代码中,你借用了两次相同的变量,违反了我写的第三条规则

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-01
    • 1970-01-01
    • 2018-09-11
    • 2014-04-12
    • 1970-01-01
    • 2016-03-05
    • 1970-01-01
    相关资源
    最近更新 更多