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

时间:2019-09-06 21:12:27

标签: 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);
    }
}

此循环应该基于thisthat起作用-但是借用会引发此错误:

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

或在较新版本的Rust中:

error[E0596]: cannot borrow data in an index of `std::vec::Vec<&mut std::string::String>` as mutable
 --> src/lib.rs:5:32
  |
5 |             if collection[j] < collection[least_element] {
  |                                ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
  |
  = help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `std::vec::Vec<&mut std::string::String>`

使&引用可变是不是更有意义?

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

Error 0596解释了在尝试从不可变值借来但least_element可变时发生的情况。如果将i更改为mut i,则也会进行编译(并且编译器建议从mut中删除i)。

有一个可以照亮它的锈菌吗?

1 个答案:

答案 0 :(得分:2)

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