RustのarrayとVec

つぎのRustコードは、rustc 1.51.0でコンパイル、実行できました。

#![allow(unused)]
fn main() {
    let mut x: [i32; 2] = [0,1];
    let mut a1 = [x, [0,0]];
    let mut a2 = [x, [0,0]];
    assert_eq!(a1, [[0,1],[0,0]]);
    x[0] = 100;
    assert_eq!(x, [100,1]);
    assert_eq!(a1, [[0,1],[0,0]]);

    let mut y: Vec<i32> = vec![0,1];
    let mut v1 = vec![y, vec![0,0]]; // move
    assert_eq!(v1, [[0,1],[0,0]]);
    // y[0] = 100; // error
    // let mut v2 = vec![y, vec![0,0]]; // error
}


ここまでは事実です。


ここからは私の感想です。コードのarrayの挙動に違和感を感じました。arrayとVecはパラレルだと思い込んでいたからです。arrayのボローチェッカーをすり抜けるような挙動が想定外でした。

(原因の推測を削除しました。間違っていました。お詫び申し上げます。)

(追記 2021年4月22日)
スライス slice https://doc.rust-lang.org/std/primitive.slice.html
に関しても少し試してみます。

fn main() {
    let mut a = [1,2,3];
    let tmp = &mut a[1..];
    a[1] = 100;
    tmp[0] = 200;
}

この結果はコンパイルエラーです。

error[E0506]: cannot assign to `a[_]` because it is borrowed
  --> src\main.rs:54:5
   |
53 |     let tmp = &mut a[1..];
   |                    - borrow of `a[_]` occurs here
54 |     a[1] = 100;
   |     ^^^^^^^^^^ assignment to borrowed `a[_]` occurs here
55 |     tmp[0] = 200;
   |     ------ borrow later used here


代入の順番を変えてみます。

fn main() {
    let mut a = [1,2,3];
    let tmp = &mut a[1..];
    tmp[0] = 200;
    a[1] = 100;
}

コンパイルできます。

代入の順番を変えただけです。
なぜ、代入の順番と所有権が関係あるのか分かりません。

私はこの数か月Rustを勉強しています。私はRustで書くのが気に入ってきています。Rustのコンセプトは素晴らしいと思います。初めてのRust記事でネガティブなことを書いて申し訳ないです。本当は書きたくないのです。

arrayとsliceに関して rustc 1.51.0 のボローチェッカーは一貫性に欠けていて、おかしいと思います。ボローチェッカーのダブルスタンダードには、不安を感じます。