Rustの配列(array)初期化まとめ:[T; N]の書き方

スポンサーリンク

Rustの配列(array)初期化まとめ:[T; N]の書き方

はじめに

Rustの配列([T; N])はサイズがコンパイル時に決まる固定長のデータ構造です。スタック上に確保されるためVecより軽量ですが、サイズの扱いにRust特有のルールがあります。

この記事では配列の初期化パターンをまとめて解説します。動的にサイズが変わるVecについては「RustのVec初期化まとめ:vec!マクロからVec::newまで」を参照してください。


基本的な書き方

値を列挙して初期化する

let a: [i32; 5] = [1, 2, 3, 4, 5];
println!("{:?}", a);  // [1, 2, 3, 4, 5]

同じ値で埋める

let a = [0; 5];
println!("{:?}", a);  // [0, 0, 0, 0, 0]

let a = [true; 3];
println!("{:?}", a);  // [true, true, true]

サイズにはconst(定数)を使う

配列のサイズには変数は使えません。const か数値リテラルのみ有効です。

const SIZE: usize = 5;
let a = [0; SIZE];  // OK

let size = 5;
let a = [0; size];  // コンパイルエラー
error[E0435]: attempt to use a non-constant value in a constant

実行時にサイズが決まる場合は Vec を使います。


array::from_fn で各要素を計算して初期化する

std::array::from_fn を使うと各インデックスに対して値を計算できます。

let a: [i32; 5] = std::array::from_fn(|i| i as i32 * 2);
println!("{:?}", a);  // [0, 2, 4, 6, 8]

連番を作りたい場合:

let a: [usize; 5] = std::array::from_fn(|i| i + 1);
println!("{:?}", a);  // [1, 2, 3, 4, 5]

Defaultトレイトで初期化する

Default を実装している型は Default::default() で初期化できます。

let a: [i32; 5] = Default::default();
println!("{:?}", a);  // [0, 0, 0, 0, 0]

let a: [bool; 3] = Default::default();
println!("{:?}", a);  // [false, false, false]

let a: [String; 3] = Default::default();
println!("{:?}", a);  // ["", "", ""]

ただし Default で初期化できる配列のサイズは現在32まで(それ以上は手動実装が必要)。


多次元配列

let a: [[i32; 3]; 2] = [[0; 3]; 2];
println!("{:?}", a);  // [[0, 0, 0], [0, 0, 0]]

値を列挙する場合:

let a = [[1, 2, 3], [4, 5, 6]];
println!("{:?}", a);  // [[1, 2, 3], [4, 5, 6]]

配列とVecの使い分け

配列 [T; N] Vec Vec<T>
サイズ コンパイル時に固定 実行時に変更可能
メモリ スタック ヒープ
速度 速い やや遅い
サイズが変数 不可

サイズが決まっていてパフォーマンスを重視する場合は配列、サイズが動的に変わる場合はVecを選びます。


まとめ

方法
値を列挙 [1, 2, 3, 4, 5]
同じ値で埋める [0; 5]
インデックスから計算 std::array::from_fn(|i| i * 2)
デフォルト値 Default::default()

サイズには変数を使えない点に注意してください。実行時にサイズが決まる場合は Vec を使います。