Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A unit variant is a specific type of enum variant in Rust that contains no associated data or payload. Structurally identical to a unit struct, it consists solely of an identifier and represents a discrete, singular state within an enumeration. Because it holds no underlying data, a unit variant is isomorphic to the unit type () in terms of data capacity.

Syntax and Instantiation

Unit variants are declared using only their name, without parentheses () or curly braces {}. They are instantiated using the path separator ::.
enum ProcessState {
    Halted,   // Unit variant
    Running,  // Unit variant
    Faulted,  // Unit variant
}

// Instantiation requires no arguments
let current_state = ProcessState::Running;

Memory Layout and Discriminants

To differentiate between enum variants at runtime, the Rust compiler uses a hidden integer tag known as a discriminant. This mechanism applies to all enum variants, regardless of whether they carry a payload. For a unit variant, the discriminant is the only data required to identify the variant’s state. By default, the Rust compiler assigns discriminants starting at 0 and incrementing by 1 for each subsequent variant. However, you can explicitly assign integer values to unit variants.
enum HttpStatusCode {
    Ok = 200,           // Explicit discriminant
    BadRequest = 400,   // Explicit discriminant
    Unauthorized = 401, // Explicit discriminant
    PaymentRequired,    // Implicitly assigned 402
}
If an enum consists entirely of unit variants, it is known as a “fieldless enum” or “C-like enum”. You can cast a fieldless enum directly to an integer type using the as keyword to extract its discriminant:
let code = HttpStatusCode::BadRequest;
let numeric_code = code as i32; // Evaluates to 400

Pattern Matching

When evaluating a unit variant in a match expression or if let binding, you match against the exact identifier. Since there is no inner data to destructure, no variable binding occurs during the match.
let state = ProcessState::Halted;

match state {
    ProcessState::Halted => {
        // Matched exactly; no payload to extract
    }
    ProcessState::Running => {}
    ProcessState::Faulted => {}
}

Contrast with Other Variants and Memory Footprint

To understand unit variants technically, it is helpful to contrast them with the other two types of enum variants in Rust:
enum VariantTypes {
    UnitVariant,                             // No payload
    TupleVariant(i32, String),               // Anonymous positional payload
    StructVariant { id: i32, name: String }, // Named payload fields
}
Rust enums are conceptually implemented as tagged unions. This means the memory footprint of an enum instance is dictated by its largest variant. Consequently, an instance of UnitVariant occupies the exact same amount of memory as an instance of StructVariant or TupleVariant within the VariantTypes enum. However, the total size of an enum is not strictly the size of the largest payload plus an explicit discriminant. Rust performs niche filling optimizations (such as the null pointer optimization). If the payload of a variant contains invalid bit patterns (niches)—such as NonZeroU32, references &T, or bool—the compiler can encode the discriminant of the unit variants within those invalid bit patterns. In such cases, the enum requires no extra memory for the discriminant, and its total size is exactly equal to the size of the payload alone. If no niches are available, the enum size will equal the largest payload plus the size of the discriminant and any necessary alignment padding.
Master Rust with Deep Grasping Methodology!Learn More