0Pricing
Learn Rust Coding · レッスン

ジェネリックな構造体とenum

柔軟なデータ型を構築します。

「ジェネリックな構造体とenum」はCoddyKit上の無料Learn Rust Codingレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLearn Rust Coding学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Learn Rust Codingコースには全4レッスンが含まれています。

ジェネリックなデータ構造

関数と同じように、structやenumも1つ以上の型に対してジェネリックにできます。これにより、1つの定義で任意の型の値を保持できます。

標準ライブラリもこのように作られています。Vec<T>、Option<T>、Result<T, E>はいずれもジェネリックです。

ジェネリックなStruct

struct名の後ろで型パラメータを宣言し、それをフィールドに使います。ここではPointが同じ型Tの値を2つ保持します。

これで1つの定義から、整数の点や浮動小数点数の点などを作成できます。

struct Point<T> {
    x: T,
    y: T,
}

ジェネリックなStructの構築

インスタンスを作成すると、コンパイラーはフィールドの値からTを推論します。両方のフィールドは同じ型でなければなりません。

このプログラムでは、同じstructから整数の点と浮動小数点数の点を作成します。

struct Point<T> {
    x: T,
    y: T,
}

fn main() {
    let a = Point { x: 1, y: 2 };
    let b = Point { x: 1.5, y: 4.0 };
    println!("{} {}", a.x, b.y);
}

異なる型パラメータ

2つのパラメータを使うと、フィールドを異なる型にできます。Pair<T, U>は、整数と文字列を同時に保持できます。

フィールドを同じ型にする必要がある場合は1つのパラメータを、異なる型にできる場合は複数のパラメータを選びます。

struct Pair<T, U> {
    first: T,
    second: U,
}

ジェネリックなStructのメソッド

メソッドを追加するには、implブロックで型パラメータを繰り返します。impl<T> Point<T>では、implの後のパラメータが宣言、型名の後のパラメータが適用を表します。

ここではgetterがxフィールドへの参照を返します。

struct Point<T> {
    x: T,
    y: T,
}

impl<T> Point<T> {
    fn x(&self) -> &T {
        &self.x
    }
}

Bound付きメソッド

特定の具体的な型、またはboundを満たす型に対してだけメソッドを書くことができます。このimplはPoint<f64>だけに適用されます。

そのため、dist_from_originは浮動小数点数の点には存在しますが、整数の点には存在しません。

struct Point<T> { x: T, y: T }

impl Point<f64> {
    fn dist_from_origin(&self) -> f64 {
        (self.x * self.x + self.y * self.y).sqrt()
    }
}

ジェネリックなEnum

enumもジェネリックにできます。各variantはジェネリックなデータを保持できます。これは、Some(T)またはNoneのどちらかになる標準のOptionと同じ仕組みです。

自分で定義してみると、ライブラリの型がどのように動くかを理解しやすくなります。

enum Maybe<T> {
    Just(T),
    Nothing,
}

Enumの2つのパラメータ

Resultは2つのパラメータを使うため、成功値とエラー値を異なる型にできます。ここでは簡略化したバージョンを示します。

enumで複数の型パラメータを使うことで、エコシステム全体で柔軟なエラー処理が可能になります。

enum Either<L, R> {
    Left(L),
    Right(R),
}

ジェネリックなEnumのパターンマッチ

ジェネリックなenumにも、具体的なenumとまったく同じようにパターンマッチを使えます。bound付きのペイロードは、各arm内のバインディングになります。

このプログラムでは、独自のMaybeをアンラップし、含まれる値または代替値を出力します。

enum Maybe<T> { Just(T), Nothing }

fn main() {
    let m: Maybe<i32> = Maybe::Just(5);
    match m {
        Maybe::Just(n) => println!("got {}", n),
        Maybe::Nothing => println!("empty"),
    }
}

値のラップ

よくあるパターンとして、型Tのフィールドを1つ持ち、ヘルパーメソッドを備えたwrapper structがあります。ここでのWrapperは任意の値を保持して返します。

これはnewtypeパターンやスマートポインター風の型の基礎になります。

struct Wrapper<T> { inner: T }

impl<T> Wrapper<T> {
    fn new(v: T) -> Self {
        Wrapper { inner: v }
    }
}

fn main() {
    let w = Wrapper::new("hi");
    println!("{}", w.inner);
}

実行時オーバーヘッドなし

ジェネリックなstructとenumも単相化されます。Point<i32>とPoint<f64>は、コンパイル後に完全に特化された2つの異なる型になります。

ジェネリック型自体のために、隠れた間接参照やタグが追加されることはありません。

クイックチェック

ジェネリックなstructとenumについての理解度を確認しましょう。

まとめ

structとenumは名前の後ろで型パラメータを宣言し、それをフィールドやvariantに使います。これにより、OptionやResultのような再利用可能なコンテナを作れます。

メソッドではimpl<T>にパラメータを繰り返し記述し、具体的な型に特化したimplブロックも書けます。すべては単相化されるため、オーバーヘッドはありません。

よくある質問

「ジェネリックな構造体とenum」レッスンは無料ですか?

はい。「ジェネリックな構造体とenum」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Learn Rust Codingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Learn Rust Codingコースには全4レッスンが含まれています。

「ジェネリックな構造体とenum」で何を学びますか?

柔軟なデータ型を構築します。 ブラウザで直接実行するハンズオンコードでLearn Rust Codingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Learn Rust Codingを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのLearn Rust Codingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「ジェネリックな構造体とenum」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このLearn Rust Codingレッスンでコードを書いて実行できますか?

はい。すべてのLearn Rust Codingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. ジェネリック関数
  2. ジェネリックな構造体とenum
  3. トレイト境界
  4. where句と複数の境界
← Learn Rust Codingに戻る