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 を使います。