Can I skip enum pattern check if I'm certain?

Can I ignore some enum fields if I'm certain the variable is a specific enum?

Here's my code.

#[derive(Debug)]
struct Info {
    start_time: u32
}

#[derive(Debug)]
enum State {
    Running(Info),
    Stopped
}

fn main() {
    let info = Info { start_time: 333 };
    let state = State::Running(info);
    if let State::Running(state_info) = &state {
        println!("{state_info:?}");
        println!("{state:?}");
    } else {
        panic!("shouldn't be happen");   // This shouldn't happen..
    }
}

enum State moves the struct Info after initialized. So if I want to work on Info afterward, I can't keep the reference to old info but must get it again.

However, in the above pattern, Rust compiler enforces to check all possible enums, so I should use if let. Can I achieve the same without unnecessary code? I wonder if I can do the same without if let / match / extra helper function / extra code depth / ...

No, your patterns have to be exhaustive at all times. If you find yourself doing this a lot, then your code is probably ill-structured and you should refactor it so that any variant-specific handling happens before wrapping the inner value in an enum.

3 Likes

if you feel the code is "unnecessary", chances are you have a design problem. as @H2CO3 suggested, you should consider refactor your code.

the closest thing you can do is to use let else with a unreachable!() assertion (or use the unsafe unreachable_unchecked hint if you know what you are doing).

rust enum is a sum type, and it's used for situations which the "shape" of the data can change at runtime. if you find yourself only need one particular "variant" at compile time, you probably want to use other constructs, like the typestate pattern.

https://cliffle.com/blog/rust-typestate/

1 Like

You can also add a method to State to reduce the amount of repetitive typing:

impl State {
    pub fn unwrap_running(&self)->&Info {
        match self {
            State::Running(info) => info,
            _ => panic!("Not running! ({self:?})")
        }
    }
}
2 Likes

Well, the actual code contains thread pool for handling incoming operations, so I only want to configure struct Info after I set state to State::Running. I'm not sure whether refactoring can help, but thank you for the confirmation.

This is what I'm doing right now :slight_smile: Thanks.

Thank you for the rich information. I'll have a look.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.