我知道你不能同时创建一个对象的两个可变引用.我不完全理解以下代码为什么有效:

fn main() {
    let mut string = String::from("test");
    let mutable_reference: &mut String = &mut string;
    mutable_reference.push_str(" test");
    // as I understand it, this creates a new mutable reference (2nd?)
    test(&mut *mutable_reference);

    println!("{}", mutable_reference);
}

fn test(s: &mut String) {
    s.push_str(" test");
}

推荐答案

The rule

在任何时间点,对于特定值,只能有一个usable可变参考.

这不是spatial exclusion(同一件作品可以有多处引用),而是temporal exclusion.

The mechanism

为了执行这一点,&mut T不是Copy;因此呼吁:

test(mutable_reference);

应该将引用移动到test.

实际上,这样做会使它以后无法使用,而且不符合人体工程学,因此Rust编译器会插入一个自动reborrowing,就像你自己做的那样:

test(&mut *mutable_reference);

如果你想,你可以强制移动:

test({ let x = mutable_reference; x });

The effect

再借款本质上就是借款:

  • 只要未命名的临时可变引用存在(或从中borrow 的任何内容),mutable_reference就被borrow ,
  • 未命名的临时可变引用被移动到test
  • 在表达式的末尾,未命名的临时可变引用被销毁,因此mutable_reference的borrow 结束.

Rust相关问答推荐

把Vector3变成Vector4的绝妙方法

Rust中的相互递归特性与默认实现

如何在Rust中表示仅具有特定大小的数组

Box::new()会从一个堆栈复制到另一个堆吗?

为什么允许我们将可变引用转换为不可变引用?

如何将像烫手山芋一样不透明的值从一个Enum构造函数移动到下一个构造函数?

为什么基于高山Linux的Docker镜像不能在绝对路径下找到要执行的命令?

Rust 的多态现象.AsRef与Derf

对于rustc编译的RISC-V32IM二进制文件,llvm objdump没有输出

带引脚和不带引脚的比较功能

Rust 中的复合 `HashSet` 操作或如何在 Rust 中获得 `HashSet` 的显式差异/并集

使用占位符获取用户输入

为什么某些类型参数仅在特征边界中使用的代码在没有 PhantomData 的情况下进行编译?

在 Rust 中实现资源消耗的安全包装器

仅当函数写为闭包时才会出现生命周期错误

在 Rust 中,将可变引用传递给函数的机制是什么?

为什么拥有 i32 所有权的函数需要它是可变的?

提取 struct 生成宏中字段出现的索引

在 Rust 中有条件地导入?

如何将 while 循环内的用户输入添加到 Rust 中的向量?