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"

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

Examples

http://github.com/pdx-cs-rust/playing-cards

http://github.com/PoHuit/plan-b

Last modified: Monday, 27 January 2020, 3:45 PM