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