所有权:Rust 中元组和数组的区别

dor*_*asu 7 rust

我开始学习 Rust,在进行实验时,我发现所有权如何应用于我不理解的元组和数组的方式有所不同。基本上,以下代码显示了差异:

#![allow(unused_variables)]

struct Inner {
    in_a: u8,
    in_b: u8
}
struct Outer1 {
    a: [Inner; 2]
}

struct Outer2 {
    a: (Inner, Inner)
}

fn test_ownership(num: &mut u8, inner: &Inner) {
}

fn main() {
    let mut out1 = Outer1 {
        a: [Inner {in_a: 1, in_b: 2}, Inner {in_a: 3, in_b: 4}]
    };
    let mut out2 = Outer2 {
        a: (Inner {in_a: 1, in_b: 2}, Inner {in_a: 3, in_b: 4})
    };

    // This fails to compile
    test_ownership(&mut out1.a[0].in_a, &out1.a[1]);
    // But this works!
    test_ownership(&mut out2.a.0.in_a, &out2.a.1);
}
Run Code Online (Sandbox Code Playgroud)

第一次调用test_ownership()不会编译,正如预期的那样,Rust 会发出一个错误,抱怨同时获取对 的可变和不可变引用out1.a[_]

error[E0502]: cannot borrow `out1.a[_]` as immutable because it is also borrowed as mutable
  --> src/main.rs:27:41
   |
27 |     test_ownership(&mut out1.a[0].in_a, &out1.a[1]);
   |     -------------- -------------------  ^^^^^^^^^^ immutable borrow occurs here
   |     |              |
   |     |              mutable borrow occurs here
   |     mutable borrow later used by call
Run Code Online (Sandbox Code Playgroud)

但我不明白的是,为什么第二次调用test_ownership()不会使借用检查器发疯?似乎数组被视为一个独立于被访问索引的整体,但元组允许对其不同索引的多个可变引用。

Alo*_*oso 5

元组就像匿名结构,访问元组中的元素就像访问结构域一样

结构可以部分借用(也可以部分移动),因此&mut out2.a.0.in_a只借用元组的第一个字段。

这同样不适用于索引。索引运算符可以通过实现Indexand来重载IndexMut,所以&mut out1.a[0].in_a等价于&mut out1.a.index_mut(0).in_a。而a.0只是访问一个字段,a[0]调用一个函数!函数不能部分借用某些东西,因此索引运算符必须借用整个数组。