Niezupełnie. Co widziałem jest wprowadzenie nowego struct
dla każdego wariantu enum, a następnie sposoby na wyliczenia, aby go rozkładać:
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
}
oczywiście, nie potrzebę struct a może po prostu zwrócić u8
, ale może to być trudne do śledzenia.
Jednak w przyszłości jest jeszcze lepsze wsparcie. I Myślę, że to "efficient code reuse" RFC, ale lepiej opisane w blogu Virtual Structs Part 3: Bringing Enums and Structs Together. Propozycja polegałaby na tym, aby Animal::Cat
był samodzielnym typem, a zatem Twoja metoda mogłaby zaakceptować numer Animal::Cat
i nie musieć się o to martwić.
Osobiście prawie zawsze wolą napisać kod w mojej wrodzonej nieomylną realizację i zmusić rozmówcę do paniki:
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
}
}
}
A ja prawdopodobnie użyć 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,
}
}
}
zamiast implantów Zwierząt mam tendencję do implikowania cechy Into, jak [ten przykład placu zabaw] (http://is.gd/jmS3RB). Z prostymi wyliczeniami powinno być względnie łatwo mieć makro, które generuje importy, ale nie jest to wzór, którego używam tak bardzo, więc nigdy nie napisałem tego dookoła ... –