Rust で文字列列挙型を作成する

Nilesh Katuwal 2023年1月30日
  1. Rust で列挙型を作成する
  2. Rust の Strum
Rust で文字列列挙型を作成する

この記事では、Rust で文字列列挙型を作成する方法について学習します。

Rust で列挙型を作成する

Rust では、列挙型は複数の可能なバージョンの 1つであるデータを表します。enum キーワードは、いくつかの可能なバージョンの 1つである可能性のあるタイプの開発を許可します。

struct として有効なバージョンはすべて、enum としても有効です。さらに、列挙型の各バージョンには、オプションで関連データが含まれる場合があります。

enum Information {
    Quit,
    ChangeColor(i32, i32, i32),
    Move { x: i32, y: i32 },
    Write(String),
}

データのないバリエーション、名前付きデータのあるバリエーション、匿名データのあるバリエーションがあります。バリアントを定義するための構文は、タプル構造体のような構造体を定義するための構文を模倣しています。

個々の構造体の定義とは対照的に、列挙型は単一のタイプです。enum 値は、どのバリアントとも一致する可能性があります。

これが、列挙型がしばしば合計型と呼ばれる理由です。潜在的な列挙型値のセットは、可能なバリアント値のセットの合計です。

::構文を使用して、各バリアントの名前を参照します。この名前は、列挙型自体の名前でスコープされます。

Rust の Strum

Strum は、Rust での enums と文字列の操作を容易にする macros と特性のコレクションです。

EnumString:自動派生 std::str::FromStrenum に適用されます。各 enum バージョンはその名前と一致します。

これは、以下に示すように、属性で serialize="DifferentName"を使用するか、string="DifferentName"を使用してオーバーライドできます。同じバリエーションに多くの逆シリアル化を追加することが可能です。

バリエーションに追加のデータが含まれている場合、逆シリアル化によってそれらがデフォルト値に設定されます。default 属性は、単一のデータパラメーターを持つタプルバリエーションに適用できます。

一致するものが見つからない場合は、指定されたバリアントが返され、入力文字列がパラメーターとしてキャプチャされます。これは、EnumString 継承によって作成されたコードの例です。

#[derive(EnumString)]
enum Cars {
    BMW,
    Volvo { range:usize },

    #[strum(serialize="Toyota",serialize="b")]
    Toyota(usize),

    #[strum(disabled="true")]
    Fiat,
}

FromStr のデフォルトの実装は、バリアントの名前にのみ一致することに注意してください。DisplayToString はどちらも、指定された enum バリエーションを返します。これにより、ユニットスタイルのバリアントを enum から文字列に変換して、元に戻すことができます。

さらに、ToStringDisplay は、以下の基準に応じて適切なシリアル化を選択します。

  1. この値は、文字列プロパティが存在する場合に使用されます。バージョンごとに 1つだけ許可されます。
  2. 値が最も長いシリアル化されたプロパティが選択されます。この動作が望ましくない場合は、代わりに文字列を使用してください。
  3. 最後に、serialize プロパティも to string プロパティも存在しない場合は、バリアントの名前が使用されます。

ToString よりも Display の方が望ましい::std::fmt::Display を実装するすべてのタイプのデフォルトの実装は ToString です。

use std::string::ToString;

#[derive(Display, Debug)]
enum Cars {
    #[strum(serialize="redred")]
    BMW,
    Volvo { range:usize },
    Toyota(usize),
    Ferrari,
}

fn debug_cars() {
    let BMW = Cars::BMW;
    assert_eq!(String::from("BMWBMW"), BMW.to_string());
}

fn main () { debug_cars(); }

関連記事 - Rust String