配列とスライス

Beginner

This tutorial is from open-source community. Access the source code

はじめに

この実験では、Rust の配列とスライスを調べます。配列は、連続したメモリに格納された同じ型のオブジェクトのコレクションであり、その長さはコンパイル時に既知です。一方、スライスは配列に似ていますが、その長さはコンパイル時には既知ではありません。スライスは、配列の一部を借用するために使用できます。また、配列の作成方法、要素のアクセス方法、長さの計算方法、メモリの割り当て方法、配列をスライスとして借用する方法、空のスライスの操作方法についても説明します。さらに、.get() メソッドを使用して配列要素を安全にアクセスし、境界外エラーを処理する方法についても説明します。

注: 実験でファイル名が指定されていない場合は、好きなファイル名を使用できます。たとえば、main.rs を使用して、rustc main.rs &&./main でコンパイルして実行できます。

配列とスライス

配列は、同じ型 T のオブジェクトのコレクションであり、連続したメモリに格納されます。配列は角括弧 [] を使用して作成され、その長さはコンパイル時に既知であり、型シグネチャ [T; length] の一部を構成します。

スライスは配列に似ていますが、その長さはコンパイル時には既知ではありません。代わりに、スライスは 2 つのワードのオブジェクトです。最初のワードはデータへのポインタで、2 番目のワードはスライスの長さです。ワードサイズは usize と同じで、プロセッサアーキテクチャによって決まります。たとえば、x86-64 では 64 ビットです。スライスは、配列の一部を借用するために使用でき、型シグネチャは &[T] です。

use std::mem;

// この関数はスライスを借用します。
fn analyze_slice(slice: &[i32]) {
    println!("スライスの最初の要素:{}", slice[0]);
    println!("このスライスには {} 個の要素があります", slice.len());
}

fn main() {
    // 固定サイズの配列 (型シグネチャは不要です)。
    let xs: [i32; 5] = [1, 2, 3, 4, 5];

    // すべての要素を同じ値に初期化できます。
    let ys: [i32; 500] = [0; 500];

    // インデックスは 0 から始まります。
    println!("配列の最初の要素:{}", xs[0]);
    println!("配列の 2 番目の要素:{}", xs[1]);

    // `len` は配列内の要素数を返します。
    println!("配列の要素数:{}", xs.len());

    // 配列はスタックに割り当てられます。
    println!("配列は {} バイトを占有しています", mem::size_of_val(&xs));

    // 配列は自動的にスライスとして借用できます。
    println!("配列全体をスライスとして借用します。");
    analyze_slice(&xs);

    // スライスは配列の一部を指すことができます。
    // 形式は [開始インデックス..終了インデックス] です。
    // `開始インデックス` はスライスの最初の位置です。
    // `終了インデックス` はスライスの最後の位置の 1 つ多い位置です。
    println!("配列の一部をスライスとして借用します。");
    analyze_slice(&ys[1..4]);

    // 空のスライス `&[]` の例:
    let empty_array: [u32; 0] = [];
    assert_eq!(&empty_array, &[]);
    assert_eq!(&empty_array, &[][..]); // 同じですが、冗長です

    // 配列は `.get` を使用して安全にアクセスでき、`Option` を返します。
    // これは以下のようにマッチングできます。または、プログラムを
    // 素敵なメッセージで終了させる代わりに、幸せに続行するために
    // `.expect()` と一緒に使用できます。
    for i in 0..xs.len() + 1 { // あっ、1 要素多すぎます!
        match xs.get(i) {
            Some(xval) => println!("{}: {}", i, xval),
            None => println!("ゆっくりして!{} ははずれています!", i),
        }
    }

    // 配列の境界外インデックスはコンパイル時エラーになります。
    //println!("{}", xs[5]);
    // スライスの境界外インデックスは実行時エラーになります。
    //println!("{}", xs[..][5]);
}

まとめ

おめでとうございます!あなたは配列とスライスの実験を完了しました。あなたの技術を向上させるために、LabEx でさらに多くの実験を練習できます。