Pattern binding the same variable to different types sharing a trait

a 夏天 提交于 2021-02-11 14:49:10

问题


I have a question about pattern matching on values sharing some behaviour through a trait.

I have an enum with two variants, each binding value of different types, where both types implement a trait. I'm trying to figure out whether it's possible to create a single pattern (of the E::VarA(x) | E::VarB(x) form) in which I bind both types to a single constant, provided I'm only interested in using the shared behaviour.

An illustrative example: Playground:

trait T {
    fn f(&self) -> usize;
}

struct A;

impl T for A {
    fn f(&self) -> usize { 1 }
}

struct B;

impl T for B {
    fn f(&self) -> usize { 2 }
}

enum E {
    VarA(A),
    VarB(B),
}

fn unwrap(e: E) -> usize {
    match e {
        E::VarA(v) | E::VarB(v) => T::f(&v)
    }
}

fn main() {
    let val = E::VarA(A{});  
    println!("{}", unwrap(val));
}

The code obviously does not compile, but it shows my intentions. Is there a way to make the code work, preferably more elegant than simply splitting the pat1 | pat2 => ... into pat1 => ... ; pat2 => ... ?


回答1:


You can make a macro that unwraps to match statement.

trait T {
    fn f(&self) -> usize;
}

struct A;
impl T for A {
    fn f(&self) -> usize { 1 }
}

struct B;
impl T for B {
    fn f(&self) -> usize { 2 }
}

enum E {
    VarA(A),
    VarB(B),
}

macro_rules! unwrap {
    ($value:expr, $pattern:pat => $result:expr) => {
        match $value {
            E::VarA($pattern) => $result,
            E::VarB($pattern) => $result,
        }
    };
}

fn main() {
    let a = E::VarA(A{});
    let b = E::VarB(B{});

    println!("a:{} b:{}",
        unwrap!(a, ref sm => sm.f()),
        unwrap!(b, ref sm => sm.f()));

}



回答2:


If all variants implement this trait, the best solution is to implement the trait for the whole enum (playground).

Relevant code:

impl T for E {
    fn f(&self) -> usize {
        match self {
            E::VarA(x) => x.f(),
            E::VarB(x) => x.f(),
        }
    }
}


来源:https://stackoverflow.com/questions/60346796/pattern-binding-the-same-variable-to-different-types-sharing-a-trait

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!