所有权转移后的变异变量

iDe*_*bug 1 transfer ownership rust

我知道如何使代码工作我只是想知道为什么会这样。

假设有以下程序:

fn dummy(name: String) {
    let last_name = " Wang".to_string();
    name.push_str(&last_name);
    println!("Hello, {}", name);
}

fn main() {
    println!("What is your name?");
    let mut name = String::new();
    std::io::stdin().read_line(&mut name).expect("Couldn't read input!");
    name.pop();
    dummy(name);
}
Run Code Online (Sandbox Code Playgroud)

当尝试编译它时,出现以下错误:

error[E0596]: cannot borrow `name` as mutable, as it is not declared as mutable
 --> print.rs:3:5
  |
1 | fn dummy(name: String) {
  |          ---- help: consider changing this to be mutable: `mut name`
2 |     let last_name = " Wang".to_string();
3 |     name.push_str(&last_name);
  |     ^^^^ cannot borrow as mutable

error: aborting due to previous error

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

我知道只需在函数定义中添加mutnext 就可以解决这个问题,但是当变量先前name在函数内部定义为可变时,为什么需要在函数定义中将其声明为可变呢?namemain

难道编译器不应该知道变量之前是可变的吗?为什么它不能随之转移所有权和可变的“属性”?

也许这是一个愚蠢的问题,但我是 Rust 新手。如果它的行为如此,是否会带来一些新问题/错误的可能性?如果是,您能举一些例子吗?

pro*_*-fh 5

作为参数传递的事实name只是一个细节。在这个简化的示例中,我们可以重现相同的效果。

fn main() {
    let mut name1 = "first".to_owned();
    name1.push_str(" second");
    let mut name2 = name1;
    name2.push_str(" third");
    let name3 = name2;
    // name3.push_str(" fourth"); // rejected
    let mut name4 = name3;
    name4.push_str(" fifth");
    println!("{}", name4);
}
Run Code Online (Sandbox Code Playgroud)

字符串的所有权从name1变为name2name3然后name4这些变量(绑定)中的每一个都决定(有或没有mut)现在唯一所有者的字符串是否可以被改变。

初始化函数的参数类似于初始化另一个变量(借用/所有权转移/复制...),并且一旦在函数内部,该参数就被视为在此上下文中可能可变或不可变的任何其他局部变量。如果您打算修改此参数,您可以使用 声明它mut或将其传输到使用 声明的另一个局部变量mut

请注意,我们在这里处理的是,而不是引用。当然,您不能&mut T从 a初始化 a &T。但是在引用前面加上mut前缀(如mut &Tmut &mut T)可以将此引用重新分配给另一个值(是否可变,取决于 right mut)。如果您熟悉 C 或 C++,这类似于const在声明指针时在星号之前或之后(或两侧)使用。

简而言之,在变量上使用与您在算法中修改此变量中存储的内容的意图mut相关,但它不是此变量内容的属性。