rust - Rust 的借用检查器在这里真正提示的是什么?

标签 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)。

是否有 Rustacean 可以阐明这一点?

最佳答案

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

关于rust - Rust 的借用检查器在这里真正提示的是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57828602/

相关文章:

rust - 不使用标准库时如何迭代搜索并从列表中删除

rust - 了解在迭代器上调用方法两次时如何满足借用检查器?

loops - 引用的生命周期比相同范围内的值短?

callback - 将结构方法设置为回调

rust - 将包含引用的结构移动到静态闭包中不起作用

visual-studio-code - 为什么 `cargo build` 无法在 VS Code 中编译 structopt-derive?

gtk - rust 和 GTK+3。如何创建包含可以转换为 &[&ToValue] 类型的 glib::Value 类型元素的数组?

rust - 如何在不将可变引用传递给函数的情况下重新借用它?

rust - 如何创建一个可以在 Rust 中作为参数传递的字符串数组?

c - LLVM 作为不同语言的基础编译器