How to match over self in an enum?

后端 未结 1 1782
借酒劲吻你
借酒劲吻你 2020-12-10 12:16

I have an enum:

enum Expr {
    Lit(u32),
    Var(Id),
    Ass(Id, u32),
    Add(u32, u32),
    Sub(u32, u32),
    Mul(u32, u32),
}

I\'m tr

相关标签:
1条回答
  • 2020-12-10 13:07

    For the first question, you need to use the ref keyword, as said by @Adrian:

    impl Expr {
        fn eval(&self, env: &mut Env) -> Result<u32, String> {
            use Expr::*;
    
            match *self {
                Lit(l) => Ok(l),
                Var(ref id) => env.lookup(id).ok_or_else(|| format!("undefined var {:?}", id)),
                Ass(ref id, v) => {
                    env.assign(id.clone(), v);
                    Ok(v)
                }
                Add(f, s) => Ok(f + s),
                Sub(f, s) => Ok(f - s),
                Mul(f, s) => Ok(f * s),
            }
        }
    }
    

    Using ref prevents the pattern matching from taking ownership of id. As you mention, you are not allowed to take the value of id out of the Expr because you only have an immutable reference. v, f, and s don't have this problem because they are u32, which implements Copy. Instead of taking the value out, they are copied, leaving the original in place.

    I don't know what the Env or Id type are, or the definitions of lookup and assign, so perhaps some clone() calls are not necessary.

    For your second question, this is because self is of type &Expr, so you need to include & in the patterns:

    impl Expr {
        fn eval(&self, env: &mut Env) -> Result<u32, String> {
            use Expr::*;
    
            match self {
                &Lit(l) => Ok(l),
                &Var(ref id) => env.lookup(id).ok_or_else(|| format!("undefined var {:?}", id)),
                &Ass(ref id, v) => {
                    env.assign(id.clone(), v);
                    Ok(v)
                }
                &Add(f, s) => Ok(f + s),
                &Sub(f, s) => Ok(f - s),
                &Mul(f, s) => Ok(f * s),
            }
        }
    }
    

    Both forms of matching are equivalent, but *self is more idiomatic and requires less typing :)

    0 讨论(0)
提交回复
热议问题