第11章 列挙型
この章の目的
この章を終えるころには、固定された選択肢の集合のうち正確に1つである値を記述できるようになります。
固定された集合のうちの1つ
構造体は同時に存在する複数の事実を束ねます。一方で、値がある小さく固定された可能性の集合のうち正確に1つであることもあります。音のアーティキュレーションは、スタッカート、レガート、アクセントのうちの1つです。それは常に正確に1つです。そのような値は列挙型で記述されます。
列挙型の宣言とマッチ
列挙型における各選択肢はバリアントと呼ばれます。
enum Articulation {
Staccato,
Legato,
Accent,
}
fn length_percent(a: Articulation) -> Word {
match a {
Articulation::Staccato => 50,
Articulation::Legato => 100,
Articulation::Accent => 90,
}
}
fn main() -> Word {
length_percent(Articulation::Staccato)
}
実行してください。出力は 50 です。スタッカートの音は、記譜された長さの約半分だけ保持されます。
バリアントは、列挙型名、二重コロン、バリアント名の順で名付けられ、Articulation::Staccato のように書きます。match は値がどのバリアントであるかを検査し、合致するアームを選びます。
この match には _ のすべてを受け止めるケースがないことに注目してください。それは必要ありません。言語は Articulation のすべてのバリアントを把握しており、3つすべてが列挙されているため、この match は網羅的です。もしあるバリアントが省かれていれば、プログラムは実行される前に拒否されます。これは本物の安全網です。後で4つ目のアーティキュレーションを追加すると、それを処理し忘れたすべての match が直ちに捕捉されます。
値を保持するバリアント
バリアントは自身の値を保持することもできます。音程は、ユニゾン、あるいは何半音かの上昇、あるいは下降であるかもしれません。
enum Interval {
Unison,
Up(Word),
Down(Word),
}
fn semitone_shift(i: Interval) -> Word {
match i {
Interval::Unison => 0,
Interval::Up(n) => n,
Interval::Down(n) => 0 - n,
}
}
fn main() -> Word {
semitone_shift(Interval::Up(7))
}
実行してください。出力は 7 です。バリアント Up と Down はそれぞれ Word を保持します。Interval::Up(n) のように match アームがその保持された値に名前を付けると、その値はアーム内で n として利用可能になります。そのようなバリアントの構築は関数呼び出しのように見えます。Interval::Up(7) です。
この章のまとめ
enum Name { Variant, ... }は固定された集合のうちの1つである値を宣言します。Name::Variantはバリアントを名付け、matchはそれに基づいて選択します。- 列挙型に対する
matchはすべてのバリアントを網羅しなければならず、言語がこれを検査します。 - バリアントは
Variant(Type)と書いて値を保持することができ、matchアームはその保持された値に名前を付けて使用できます。 Wordは、列挙型をその判別子にキャストすることの逆である判別子から列挙型への構文d as Name { ... }を用いて、列挙型の値に戻すことができます。第23章を参照してください。
次章では、名前によってではなく位置によって値をまとめます。