kmizu:いい疑問だと思います。まず、RustのEnumはenumという名前こそついていますが、たとえばCやC++、C#、Javaなどのenumとは全くの別物であるということを言っておきたいと思います。専門的に言えば、Rustのenumは代数的データ型(Algebraic
Data Type)と呼ばれる概念を表現するためのもので、関数型プログラミング言語であるMLやHaskellなどの影響を受けたものです。
さて、では何故代数的データ型あると便利かという話なのですが、以下のように
・整数
・加算/減算/乗算/除算
ができる数式のデータ構造を表現することを考えます。これはRustで次のように書くことができます。
enum Expression {
Number(f64),
Addition(Box<Expression>, Box<Expression>),
Subtraction(Box<Expression>, Box<Expression>),
Multiplication(Box<Expression>, Box<Expression>),
Division(Box<Expression>, Box<Expression>),
}
数式やプログラミング言語は「木構造」としてみなせるデータのですた、木構造はこういう風にenumを使うと簡潔に表現できます。上記の構造をクラスとして表現することも可能ですが、表現としてとても冗長になることは間違いありませんし、実際代数的データ型がない言語では冗長な表現を強いられます。また、このようにして表現されたデータ構造を処理するプログラムも以下のように書くことができ、便利です。
fn eval(expr: Expression) -> f64 {
match expr {
Expression::Number(n) => n,
Expression::Addition(lhs, rhs) => eval(*lhs) + eval(*rhs),
Expression::Subtraction(lhs, rhs) => eval(*lhs) - eval(*rhs),
Expression::Multiplication(lhs, rhs) => eval(*lhs) eval(rhs),
Expression::Division(lhs, rhs) => eval(*lhs) / eval(*rhs),
}
}
これはenumに加えてパターンマッチを使ったコードです。同様の表現をオブジェクト指向のクラスを使って書くこともできますが、switch-case+キャストあるいはVisitorパターンといった形で冗長な記述になるのが欠点です。
ともあれ、このように構造化されたデータ、特に木構造を処理するときにRustのenumおよびパターンマッチは便利に使うことができます。