如何实现枚举及其各自变体的特征?

时间:2019-07-16 22:59:15

标签: enums rust

我正在尝试使用枚举变量来捕获本质上是异构的(具有不同的字段集合)但从协议角度来看属于相同“类型”的数据。但是,我不确定如何实现特定于子类型的方法和特征。这是一个最小的示例,说明如何创建数据枚举以及可以使用枚举变量构造函数来指定类型,但是如果我在变量上实现特征,则无法确定调用该函数的方法

use std::fmt;

enum Data {
    N(NData),
    S(SData),
}

struct NData {
    numeric: u32,
}

impl fmt::Display for NData {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.numeric)
    }
}

struct SData {
    stringy: Vec<String>,
}

fn main() {
    let d_n: Data = Data::N(NData { numeric: 0x0 });
    let n = NData { numeric: 0xff };

    // Fails, fmt::Display not implemented for Data
    println!("{}", d_n);

    // Just fine!
    println!("{}", n);
}

1 个答案:

答案 0 :(得分:6)

一种可能的解决方案是对变体以及enum实施特征,正如您在此处看到的那样,它仅调用变体的特定实现:

use std::fmt;

struct NData {
    numeric: u32,
}

impl fmt::Display for NData {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.numeric)
    }
}

struct SData {
    strings: Vec<String>,
}

impl fmt::Display for SData {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self.strings)
    }
}

enum Data {
    N(NData),
    S(SData),
}

impl fmt::Display for Data {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Data::N(n_data) => n_data.fmt(f),
            Data::S(s_data) => s_data.fmt(f),
        }
    }
}

fn main() {
    let n = NData { numeric: 0xff };
    let s = SData { strings: vec!["hello".to_string(), "world".to_string()] };

    println!("{}", n);
    println!("{}", s);

    let d_n = Data::N(n);
    let d_s = Data::S(s);

    println!("{}", d_n);
    println!("{}", d_s);
}

这将产生以下输出:

255
["hello", "world"]
255
["hello", "world"]