为什么有时可能从不可变数组中借用&mut引用?

cha*_*pok 8 rust

让我们尝试编译这段代码:

trait Bar {
    fn bar(&mut self);
}

fn foo(a1: &mut Bar, j: usize) {
    let a = [a1];
    a[0].bar(); //compilation ok
    a[j % 2].bar();
}

fn main() {}
Run Code Online (Sandbox Code Playgroud)

编译错误:

error[E0596]: cannot borrow immutable local variable `a` as mutable
 --> src/main.rs:8:5
  |
6 |     let a = [a1];
  |         - consider changing this to `mut a`
7 |     a[0].bar(); //compilation ok
8 |     a[j % 2].bar();
  |     ^ cannot borrow mutably
Run Code Online (Sandbox Code Playgroud)

为什么a[0].bar()好,但a[j % 2].bar()失败了?这是编译器错误吗?

She*_*ter 4

这是编译器错误吗?

是的PR 47167在 Rust 1.25.0-nightly (2018-01-09 61452e506f0c88861cccaeea4ced3419bdb3cbe0) 中修复了该问题

简而言之,有两种执行索引的方法,称为“内置索引”和“重载索引”。正如您可能从名称中猜测到的那样,一个是编译器固有的,另一个是用户可以自定义的。

在这种情况下,超载索引正在执行不必要的数组借用,从而触发警告。您可以通过简化类型推断的编译器工作来解决该问题:

fn foo(a1: &mut Bar, j: usize) {
    let a = [a1];
    let x: usize = j % 2;
    a[x].bar();
}
Run Code Online (Sandbox Code Playgroud)

通过明确声明索引是 a usize,代码现在将使用内置索引。