如何用这个简单的代码满足Rust借用检查器?

LiL*_*Lei 6 rust

我从借用检查器收到Rust编译错误,并且不知道如何解决它.
下面的代码很简单,C++中的类似代码没有问题.

fn main() {
    let mut nums = vec![1, 2, 3];
    if let Some(x) = nums.last() {
        nums.push(*x);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是错误:

message: 'cannot borrow `nums` as mutable because it is also borrowed as immutable (4, 9)'
Run Code Online (Sandbox Code Playgroud)

Jan*_*ner 7

当你打电话给.last()你借用nums不可变的时候,因为它会改变它会使x你持有的引用无效.然后你打电话.push,借用nums可变的.

问题是你现在有一个不可变的和可变的同时借用相同的值,这是生锈的内存安全保证(多个读者一个单独的作者保证你永远不会有任何无效的内存).

fn main() {
    let mut nums = vec![1, 2, 3];
    if let Some(x) = nums.last() { // Immutable borrow starts here
        nums.push(*x);             // Mutable borrow starts here
    }                              // Immutable and mutable borrows end here
}
Run Code Online (Sandbox Code Playgroud)

根据@ DanielSanchez的例子,解决方案是通过立即删除其结果的引用来降低不可变借位的范围:

let mut nums = vec![1, 2, 3];
if let Some(&x) = nums.last() { // Immutable borrow starts and ends here
    nums.push(x);               // Mutable borrow starts here
}                               // Mutable borrow ends here
Run Code Online (Sandbox Code Playgroud)

  • 在这种情况下,`&x`实际上取消引用`x`.通常,这会移动`x`,但是整数实现`Copy`特性,这意味着我们不使用`x`而是使用自动生成的`x`副本.我们解除引用`x`会破坏`.last()`返回的引用,并结束它引起的借用. (2认同)

Net*_*ave 5

您可以取消引用guard子句中的引用:

fn main() {
    let mut nums = vec![1, 2, 3];
    if let Some(&x) = nums.last() {
        nums.push(x);
    }
}
Run Code Online (Sandbox Code Playgroud)

Rust具有强大的模式匹配功能,如果您知道它的类型,您可以解压几乎所有内容.检查Rust模式匹配文档.