为什么在对该变量的可变引用可以使用时,不能使用可变变量?

Pro*_*000 2 rust

我有一个可变的字符串变量,一个不可变的变量绑定到可变字符串变量的可变引用.

let mut string = String::from("test");
let variable: &mut String = &mut string;
variable.push_str(" test");
string.push_str(" test");
Run Code Online (Sandbox Code Playgroud)

这失败了:

error[E0499]: cannot borrow `string` as mutable more than once at a time
 --> src/main.rs:5:5
  |
3 |     let variable: &mut String = &mut string;
  |                                      ------ first mutable borrow occurs here
4 |     variable.push_str(" test");
5 |     string.push_str(" test");
  |     ^^^^^^ second mutable borrow occurs here
6 | }
  | - first borrow ends here
Run Code Online (Sandbox Code Playgroud)
  1. 没有第二个变量是可变的,为什么我能够打电话push_str
  2. 为什么我能够调用push_str第二个变量而不是第一个?

Vla*_*eev 5

您收到此错误是因为可变借用是独占的:

let mut string = String::from("test")
let variable = &mut string;
Run Code Online (Sandbox Code Playgroud)

在这里,您可以创建对变量的可变引用; 因为可变引用意味着独占访问,现在无法访问原始变量,因为否则您将违反别名保证.

考虑一下:

let mut string = String::from("test");
{
    let variable = &mut string;
    variable.push_str(" test");
}
string.push_str(" test");
Run Code Online (Sandbox Code Playgroud)

此代码将按预期编译和工作,因为在再次访问原始变量之前,可变引用超出范围.

您可以在Rust书中阅读更多相关信息(请参阅本书第二版的链接).

至于为什么你可以在非mut变量上调用mutating方法,那么很可能只是因为该push_str()方法接受了它的接收器&mut; 如果你已经拥有&mut它,那么直接使用它,但是如果你没有,那么Rust会自动尝试为你创建一个,如果变量不是,那么这是不可能的mut:

let mut string = String::from("test");

string.push_str("test");
// equivalent to:
String::push_str(&mut string, "test");  // won't work if `string` is not `mut`

let variable = &mut string;
variable.push_str("test");
// [almost] equivalent to:
String::push_str(variable, "test");  // works because `variable` is already `&mut`
Run Code Online (Sandbox Code Playgroud)

我在上面的示例中写了"几乎",因为在这种情况下还有另一个称为重新延长的步骤,它基本上确保了在此调用之后可以再次使用可变引用而不是移动到函数调用中,但它并不重要这个答案.