Enums 已知枚举变量时展开内部类型
我有此枚举类型:Enums 已知枚举变量时展开内部类型,enums,rust,Enums,Rust,我有此枚举类型: enum Animal { Dog(i32), Cat(u8), } 现在我有一个函数,它将这个类型作为参数。我知道(出于某种原因)输入总是一个Cat。我想做到这一点: fn count_legs_of_cat(animal: Animal) -> u8 { if let Animal::Cat(c) = animal { c } else { unreachable!() } } 我可以写得更短和/或更地道吗?不太好。我看到的是为每个枚举变量
enum Animal {
Dog(i32),
Cat(u8),
}
现在我有一个函数,它将这个类型作为参数。我知道(出于某种原因)输入总是一个Cat
。我想做到这一点:
fn count_legs_of_cat(animal: Animal) -> u8 {
if let Animal::Cat(c) = animal { c } else { unreachable!() }
}
我可以写得更短和/或更地道吗?不太好。我看到的是为每个枚举变量引入一个新的
struct
,然后使用枚举上的方法对其进行分解:
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
}
当然,您不需要结构,只需返回u8
,但这可能很难跟踪
不过,在未来,这方面会有更好的支持。我认为这是最好的,但在博客文章中描述得更好。建议将Animal::Cat
作为一个独立类型,这样您的方法就可以接受Animal::Cat
,而不必担心它
就我个人而言,我几乎总是喜欢在我固有的实现中编写绝对正确的代码,并迫使调用方惊慌失措:
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
}
}
}
试试板条箱,它的工作原理和谢普马斯特的答案完全一样。我倾向于将这种特性植入动物身上,比如说。对于简单的枚举,使用宏来生成impl应该相对容易,但这不是我经常使用的模式,所以我从来没有真正花时间来编写它……到2019年,这段代码实际上在稳定的环境下工作——自从提出这个问题以来,枚举得到了改进。请参阅:@alias65536该代码在当时也能正常工作。问题是,是否有更好的方法可以做到这一点。也许你可以添加一个例子,说明如何使用板条箱?
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,
}
}
}