Nicht wirklich. Was ich gesehen habe, ist es, eine neue struct
für jede Enum-Variante einzuführen, und dann Methoden auf dem ENUM es zersetzen:
struct Dog(i32);
struct Cat(u8);
enum Animal {
Dog(Dog),
Cat(Cat),
}
impl Animal {
fn cat(self) -> Cat {
if let Animal::Cat(c) = self { c } else { panic!("Not a cat") }
}
fn dog(self) -> Dog {
if let Animal::Dog(d) = self { d } else { panic!("Not a dog") }
}
}
// Or better an impl on `Cat` ?
fn count_legs_of_cat(c: Cat) -> u8 {
c.0
}
Natürlich, du nicht Notwendigkeit die Struktur und man konnte nur die u8
zurückkehren , aber das kann schwer zu verfolgen sein.
Dafür gibt es in der Zukunft jedoch einen besseren Hinweis. I denke, ist es die "efficient code reuse" RFC, aber besser im Blog Post Virtual Structs Part 3: Bringing Enums and Structs Together beschrieben. Der Vorschlag wäre, Animal::Cat
als eigenständigen Typ zuzulassen, also könnte Ihre Methode eine Animal::Cat
akzeptieren und muss sich nicht darum kümmern.
Persönlich bevorzuge ich fast immer den unfehlbar Code in meiner inhärenten Implementierung zu schreiben und die Anrufer in Panik erzwingen:
impl Animal {
fn cat(self) -> Option<Cat> {
if let Animal::Cat(c) = self {
Some(c)
} else {
None
}
}
fn dog(self) -> Option<Dog> {
if let Animal::Dog(d) = self {
Some(d)
} else {
None
}
}
}
Und ich würde wahrscheinlich ein match
impl Animal {
fn cat(self) -> Option<Cat> {
match self {
Animal::Cat(c) => Some(c),
_ => None,
}
}
fn dog(self) -> Option<Dog> {
match self {
Animal::Dog(d) => Some(d),
_ => None,
}
}
}
verwenden anstelle des impl Tiers tendiere ich dazu, das Into-Merkmal zu impli- zieren, wie [dieses Spielplatzbeispiel] (http://is.gd/jmS3RB). Bei einfachen Enums sollte es relativ einfach sein, ein Makro zu haben, um die Impls zu erzeugen, aber es ist kein Muster, das ich so oft benutze, so dass ich nie dazu gekommen bin es zu schreiben ... –