Rust的借位检查员在这里真正抱怨什么?

Non*_*714 8 rust borrow-checker

考虑对一个简单的选择排序&mut Vec<&mut String>

fn selection_sort(collection: &mut Vec<&mut String>) {
    for i in 0..collection.len() {
        let mut least_element = i;
        for j in (i + 1)..collection.len() {
            if collection[j] < collection[least_element] {
                least_element = j;
            }
        }

        collection.swap(least_element, i);
    }
}
Run Code Online (Sandbox Code Playgroud)

这个循环应该工作的基础上,这个那个 -但借引发此错误:

fn selection_sort(collection: &mut Vec<&mut String>) {
    for i in 0..collection.len() {
        let mut least_element = i;
        for j in (i + 1)..collection.len() {
            if collection[j] < collection[least_element] {
                least_element = j;
            }
        }

        collection.swap(least_element, i);
    }
}
Run Code Online (Sandbox Code Playgroud)

或在较新版本的Rust中:

error[E0596]: cannot borrow data in a `&` reference as mutable
  --> src/main.rs:58:28
   |
58 |             if chunks[j] < chunks[least_element] {
   |                            ^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
   |
   = help: trait `IndexMut` is required to modify indexed content
Run Code Online (Sandbox Code Playgroud)

&引用是可变的更有意义吗?

IndexMut文档没有使用我很好理解的示例,并且有一个很大的示例,似乎没有清楚地演示如何使用IndexMut,尤其是在选择排序或交换元素的情况下。

错误0596解释了尝试从不least_element可变值中借用但发生可变时发生的错误。如果i更改为,mut i也会进行编译(编译器建议mut从中删除i)。

有没有一个可以说明这一点的锈菌?

小智 2

当您尝试访问 时collection[j],编译器会返回 a,&mut String因为这是向量元素的类型。当您尝试访问 时collection[least_element],借用检查器不知道是否为least_element != j,并且同一元素的两个可变引用将是未定义的行为。您可以使用std::ops::Indexwhich 返回 a &&mut String(并且对同一个可变引用有两个不可变引用是安全的),直接借用元素 ( &collection[j] < &collection[least_element]),或者如果可能,将集合类型更改为Vec<&String>or Vec<String>