Rust

【Rust】第4章第5回:構造体と列挙型を組み合わせた実践例

本記事では、Rustの構造体(Struct)と列挙型(Enum)を組み合わせて、より柔軟なデータ構造を設計する方法について解説します。実際のプログラムでの活用例を通じて、Rustの強力な型システムを理解しましょう。

0. 記事の概要

この記事を読むメリット

  • Rustの構造体と列挙型を組み合わせた設計ができる: より表現力豊かなデータ構造を作成できます。
  • 可読性の高いコードを記述: 複雑な状態管理をシンプルに表現できます。
  • 安全なデータ管理: Rustの型システムを活用し、バグを未然に防ぐことが可能です。

この記事で学べること

  • 構造体と列挙型の組み合わせ方
  • パターンマッチングを活用したデータ処理
  • 実践的なRustプログラムの設計手法

1. 構造体と列挙型の組み合わせ

1.1 基本的な組み合わせ

構造体の中に列挙型をフィールドとして持たせることで、複数の状態を表現できます。

enum Status {
    Active,
    Inactive,
    Suspended,
}

struct User {
    username: String,
    email: String,
    status: Status,
}

fn main() {
    let user = User {
        username: String::from("rustacean"),
        email: String::from("rust@example.com"),
        status: Status::Active,
    };
    match user.status {
        Status::Active => println!("{} is active", user.username),
        Status::Inactive => println!("{} is inactive", user.username),
        Status::Suspended => println!("{} is suspended", user.username),
    }
}

動作解説

ユーザーの状態をStatus列挙型で管理し、パターンマッチングを用いて処理を分岐させています。

2. 列挙型のバリアントに構造体を含める

2.1 詳細な状態管理

列挙型の各バリアントに構造体を含めることで、異なるデータを保持できます。

struct ActiveStatus {
    login_count: u32,
}

enum UserStatus {
    Active(ActiveStatus),
    Inactive,
    Banned(String),
}

fn main() {
    let status = UserStatus::Active(ActiveStatus { login_count: 5 });
    match status {
        UserStatus::Active(data) => println!("Login count: {}", data.login_count),
        UserStatus::Inactive => println!("User is inactive"),
        UserStatus::Banned(reason) => println!("Banned: {}", reason),
    }
}

動作解説

ログイン回数を持つActiveStatusを定義し、列挙型のバリアントにデータを持たせました。

3. よくあるエラーと対処法

  • 「mismatched types」エラー: 構造体や列挙型の型が適切に一致していない場合に発生。
  • 「non-exhaustive patterns」エラー: matchで全てのバリアントを網羅していない場合に発生。

4. まとめ

本記事では、Rustの構造体と列挙型を組み合わせた実践的なデータ管理方法について解説しました。次回は、モジュール(Module)の基本とコードの整理方法について学びます。