考虑对&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);
}
}
此循环应该基于this和that起作用-但是借用会引发此错误:
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
)。
有一个可以照亮它的锈菌吗?
答案 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>
。