10.1 Understanding Enums
An enum in Rust allows you to define a custom type by listing all its possible variants. This approach enhances code clarity and safety by restricting the possible values a variable of the enum type can hold. Unlike C enums, which are essentially named integer constants, Rust enums are distinct types integrated into the type system. They prevent errors common in C, such as using arbitrary integers where an enum value is expected. Furthermore, Rust enum variants can optionally hold data, making them far more versatile than their C counterparts.
10.1.1 Origin of the Term ‘Enum’
The term enum is short for enumeration, which means listing items one by one. In programming, it refers to a type composed of a fixed set of named values. These named values are the variants, each representing a distinct state or value that an instance of the enum type can possess.
10.1.2 Rust’s Enums vs. C’s Enums and Unions
In C, enum
primarily serves to create named integer constants, improving readability over raw numbers. However, C enums are not truly type-safe; they can often be implicitly converted to and from integers, potentially leading to errors if an invalid integer value is used. C also provides union
, which allows different data types to occupy the same memory location. However, managing unions safely is the programmer’s responsibility, requiring careful tracking of which union member is currently active (often using a separate tag field).
Rust combines and improves upon these concepts:
- A Rust enum defines a set of variants.
- Each variant can optionally contain associated data.
- The compiler enforces that only valid variants are used and ensures that access to associated data is safe.
This unified approach provides several advantages:
- Type Safety: Rust enums are distinct types, preventing accidental mixing with integers or other types. The compiler checks variant usage.
- Data Association: Variants can directly embed data, ranging from primitive types to complex structs or even other enums, eliminating the need for separate C-style unions and tags.
- Pattern Matching: Rust’s
match
construct provides a safe and ergonomic way to handle all possible variants of an enum, ensuring exhaustiveness.