Enums
Enums Are Disjoint Unions
AKA "sum types". Idea is to have a single value represent one of several alternatives
Alternatives can be names, or value-carrying names
Using enum
Alternatives normally carry type-qualified names
enum E { A, B } ... let x = E::A;
but there is a trick:
use E::*; let x = A;
Can impl an enum just as with a struct
Enum values come in tuple or structured form: tuple is more "normal", because…
Pattern matching is the only sane way to extract carried values from an enum
Compiler checks that all alternatives are matched, as with other types
https://play.rust-lang.org/?gist=fbde8cb698a32c782fab7cbfcd92e169
Generics and lifetimes work the same as with structs
Non-Value-Carrying enums Are "Special"
Alternatives have a corresponding usize value
Values start at 0, increase by 1
Can set values for elements (unspecified elements autoincrement, be careful)
Can cast alternative to usize, but no built-in way to convert usize to alternative
https://play.rust-lang.org/?gist=550961904c20aac0d49a78fe48bd4e0f
The "Void" enum
What should "enum Void;" mean?
Apparently no inhabitants of this type
Thus, can't really pass it around or whatever
Rust prefers the type "!" for an uninhabited type, but this isn't fully consistent in the language yet; sometimes it means "bottom"
Why Are Sum Types A Big Deal?
Avoid redundant storage, as with C union
"Tags" are managed by the language, so no tag mismatch issues
Combine (limited) convenience with type and memory safety
"And-or trees" are a thing