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 のボローチェッカーは一貫性に欠けていて、おかしいと思います。ボローチェッカーのダブルスタンダードには、不安を感じます。