In this lesson, you will learn how to use lifetime bounds to restrict the duration of external data held within an enum's variants.
The Problem: When Enums Store References
When an enum variant holds a reference, that reference cannot outlive the data it points to. If you are building a state machine where different states hold references to external context, you must ensure the compiler knows these references are valid for the entire lifecycle of the enum instance.
Without a lifetime bound, Rust might be unable to guarantee that a variant containing a reference doesn't "outlive" the data it is borrowing.
Defining Lifetime Bounds
Just like with structs, you can attach a lifetime parameter to an enum definition. This allows you to encode the dependency on external data directly into the type:
enum State<'a> {
Idle,
Processing(&'a str),
Completed,
}
In the example above, the Processing variant holds a reference to a &str. The 'a annotation tells Rust: "Instances of State cannot live longer than the data referred to in the Processing variant." If you try to pass a State containing a reference into a scope that lasts longer than the data itself, the compiler will catch it as a borrow-checker error.
State Transitions and Bounds
When transitioning states, you must ensure your logic respects these bounds. If you have a State<'a>, you cannot simply swap an Idle state for a Processing state containing data that expires sooner than 'a.
fn update_state<'a>(data: &'a str) -> State<'a> {
State::Processing(data)
}
This ensures that your state machine is safe, preventing dangling pointers if the external context is dropped while your enum still exists. By constraining the enum with a lifetime bound, you turn a potential memory safety risk into a strict, compile-time contract between your state machine and the data it tracks.
Key Takeaway: Applying lifetime bounds to enums allows you to safely store references in variants, ensuring that the enum instance is never more "long-lived" than the external data it depends on.