键入推理和借入与所有权转移

Mar*_*rds 7 ownership rust

我正在学习Rust,我遇到了一些令人困惑的行为.以下代码编译正常并按预期工作(编辑:添加除测试函数以外的代码,之前省略):

struct Container<'a> {
    contents : &'a mut i32,
}

fn main() {
    let mut one = Container { contents: &mut 5 };
    test(&mut one);
    println!("Contents: {}",one.contents);
}

fn test<'a>(mut x : &'a mut Container) {
    *x.contents += 1;
    let y = x;
    *y.contents += 1;
    x = y;
    println!("{:?}",*x.contents)
}
Run Code Online (Sandbox Code Playgroud)

现在在声明中

let y = x;
Run Code Online (Sandbox Code Playgroud)

推断出类型.因为x是类型&'a mut Container,我认为这是等价的:

let y: &'a mut Container = x;
Run Code Online (Sandbox Code Playgroud)

但是当我这样做时,编译器会遇到问题:

test_3.rs:25:5: 25:10 error: cannot assign to `x` because it is borrowed
test_3.rs:25     x = y;
                 ^~~~~
test_3.rs:23:33: 23:34 note: borrow of `x` occurs here
test_3.rs:23     let y: &'a mut Container = x;
Run Code Online (Sandbox Code Playgroud)

x在正确运作的例子中,如何借用这一点?我通过省略x = y;正确工作版本的行进行测试,编译器说:

test_3.rs:24:13: 24:14 note: `x` moved here because it has type `&mut Container<'_>`, which is moved by default
Run Code Online (Sandbox Code Playgroud)

因此,当我没有明确定义类型时,我会采取行动,否则就是借用.发生了什么,如何在明确给出类型时获得与之前相同的行为,以及在一种情况下导致移动行为的原因是什么,而在另一种情况下借用?

编辑完整的程序

Vee*_*rac 6

当你这样做

let y = x;
Run Code Online (Sandbox Code Playgroud)

一举一动.x可以这么说,所有权都被清空了y.

当你做任何一个

let y: &mut _ = x;
let y: &'a mut _ = x;
Run Code Online (Sandbox Code Playgroud)

x重新借用以帮助匹配生命周期.这粗略地转化为

let y: &mut _ = &mut *x;
let y: &'a mut _ = &mut *x;
Run Code Online (Sandbox Code Playgroud)

这留下x非空,持有别名的可变借用.因此,分配给它必须等待y被销毁.或者,您可以预先移动它

let tmp = x;
let y: &'a mut _ = tmp;
Run Code Online (Sandbox Code Playgroud)

我承认这是非显而易见的行为,如果不借用整个价值,你就无法借用价值的内容,这是一种耻辱.

  • Rust并没有禁止别名的可变借用 - 它禁止一次使用多个,或者以非词汇方式重叠它们.当你写`&mut x`时,`x`仍然是一个有效的堆栈位置 - 读取或写入它是不合法的. (3认同)