How do I use an enum in an `if` statement when I d

2019-07-16 00:32发布

I have an enum:

#[derive(PartialEq, Eq)]
enum Foo {
    A,
    B(usize),
}

I can use it in if statements involving other logic like baz:

fn bar(foo: &Foo, baz: bool) {
    if foo == &Foo::B(3) || baz {
        println!("Do stuff")
    }
}

However, this won't compile:

fn bar(foo: &Foo, baz: bool) {
    if foo == &Foo::B(_) || baz {
        println!("Do stuff")
    }
}

How do I use it in an if statement when I don't care what value B contains?

2条回答
Fickle 薄情
2楼-- · 2019-07-16 00:59

You can use std::mem::discriminant:

use std::mem::discriminant;

#[derive(PartialEq, Eq)]
enum Foo {
    A,
    B(usize),
}

fn main() {
    let to_test = Foo::B(123);
    let some_bool = true;

    if discriminant(&to_test) == discriminant(&Foo::B(0)) && some_bool {
        println!("Do stuff");
    }
}

If you have to test this a lot, I advice you to implement a method for it:

impl Foo {
    fn is_b(&self) -> bool {
        discriminant(self) == discriminant(&Foo::B(0))
    }
}
查看更多
仙女界的扛把子
3楼-- · 2019-07-16 01:02

It's probably easier to use a match in this case:

fn do_stuff() {
    println!("Do stuff")
}

fn bar(foo: &Foo, baz: bool) {
    match foo {
        &Foo::B(_) => do_stuff(),
        _ => {
            if baz {
                do_stuff();
            }
        }
    }
}

Alternatively with an if let:

fn bar(foo: &Foo, baz: bool) {
    if let &Foo::B(_) = foo {
        do_stuff();
    } else {
        if baz {
            do_stuff();
        }
    }
}

I'm not sure you can pull it all into a single condition easily, which makes you repeat do_stuff unfortunately.

查看更多
登录 后发表回答