配列

// Copyright 2024 Google LLC
// SPDX-License-Identifier: Apache-2.0

fn main() {
    let mut a: [i8; 5] = [5, 4, 3, 2, 1];
    a[2] = 0;
    println!("a: {a:?}");
}
  • 配列は、[0; 1024] のような短縮構文を使って初期化することもできます。 これは、すべての要素を同じ値で初期化したいときや、 手動で初期化するのが大変な大きな配列がある場合に便利です。

  • 配列型 [T; N] の値は、同じ型 T の要素を N 個(コンパイル時定数) 保持します。配列の長さは 型の一部 であることに注意してください。つまり、 [u8; 3][u8; 4] は 2 つの異なる型と見なされます。サイズが実行時に 決まるスライスについては、後で扱います。

  • 範囲外の配列要素にアクセスしてみてください。コンパイラはこのインデックスが 安全ではないことを判断できるため、このコードはコンパイルされません:

// Copyright 2024 Google LLC
// SPDX-License-Identifier: Apache-2.0

fn main() {
    let mut a: [i8; 5] = [5, 4, 3, 2, 1];
    a[6] = 0;
    println!("a: {a:?}");
}
  • 配列アクセスは実行時にチェックされます。Rust は可能な場合、これらの チェックを最適化によって取り除きます。つまり、コンパイラがアクセスの安全性を 証明できるなら、より高い性能のために実行時チェックを削除します。これらは unsafe Rust を使うことで回避できます。この最適化は非常に優れているため、 実行時チェックが失敗する例を示すのは簡単ではありません。次のコードは コンパイルされますが、実行時に panic します:
// Copyright 2024 Google LLC
// SPDX-License-Identifier: Apache-2.0

fn get_index() -> usize {
    6
}

fn main() {
    let mut a: [i8; 5] = [5, 4, 3, 2, 1];
    a[get_index()] = 0;
    println!("a: {a:?}");
}
  • 配列に値を代入するためにリテラルを使えます。

  • 配列はヒープに確保されません。配列はコンパイル時に分かる固定サイズを持つ 通常の値であり、つまりスタック上に置かれます。これは、配列がデフォルトで ヒープに確保されることがあるガベージコレクション言語に慣れた受講者の 想定とは異なる場合があります。

  • 配列から要素を削除する方法も、配列に要素を追加する方法もありません。 配列の長さはコンパイル時に固定されるため、実行時にその長さを変更することは できません。

デバッグ出力

  • println! マクロは、? 書式パラメータでデバッグ実装を要求します: {} はデフォルト出力を与え、{:?} はデバッグ出力を与えます。整数や 文字列のような型はデフォルト出力を実装していますが、配列はデバッグ出力しか 実装していません。つまり、ここではデバッグ出力を使わなければなりません。

  • # を追加すると、たとえば {a:#?} のように「整形表示」形式になり、 より読みやすくなることがあります。