А как насчет стиля C:
#[derive(Debug)]
enum Color {
Green { name: String },
Blue { switch: bool },
}
#[derive(Debug)]
struct Something {
size: u32,
color: Color,
}
fn main() {
let c = Something {
size: 1,
color: Color::Green {
name: "green".to_string(),
},
};
let d = Something {
size: 2,
color: Color::Blue { switch: true },
};
let vec_cd = vec![&c, &d];
println!("{:?}", &c);
println!("{:?}", &d);
println!("{:?}", &vec_cd);
let _ = c.size;
}
Если у всех вариантов есть что-то общее, зачем их разделять?
Конечно, мне тоже нужно получить доступ к не общему полю.
Это будет означать, что Rust должен определить, что делать, если фактический тип во время выполнения не содержит требуемого поля. Так что я не думаю, что Раст добавил бы это однажды.
Ты мог бы сделать это сам. Для этого потребуется несколько строк кода, но это соответствует поведению вашего кода на Haskell. Однако я не думаю, что это лучшее, что можно сделать. Haskell - это Haskell, я думаю, вам следует кодировать на Rust, а не пытаться кодировать на Haskell с помощью Rust. По общему правилу, некоторая особенность Rust взята непосредственно из Haskell, но то, что вы хотите здесь, на мой взгляд, очень странно для кода Rust.
#[derive(Debug)]
enum Something {
A { size: u32, name: String },
B { size: u32, switch: bool },
}
impl Something {
fn size(&self) -> u32 {
match self {
Something::A { size, .. } => *size,
Something::B { size, .. } => *size,
}
}
fn name(&self) -> &String {
match self {
Something::A { name, .. } => name,
Something::B { .. } => panic!("Something::B doesn't have name field"),
}
}
fn switch(&self) -> bool {
match self {
Something::A { .. } => panic!("Something::A doesn't have switch field"),
Something::B { switch, .. } => *switch,
}
}
fn new_size(&self, size: u32) -> Something {
match self {
Something::A { name, .. } => Something::A {
size,
name: name.clone(),
},
Something::B { switch, .. } => Something::B {
size,
switch: *switch,
},
}
}
// etc...
}
fn main() {
let a = Something::A {
size: 1,
name: "Rust is not haskell".to_string(),
};
println!("{:?}", a.size());
println!("{:?}", a.name());
let b = Something::B {
size: 1,
switch: true,
};
println!("{:?}", b.switch());
let aa = a.new_size(2);
println!("{:?}", aa);
}