枚举变体已知时解开内部类型 [英] Unwrap inner type when enum variant is known
问题描述
枚举动物{
狗(i32),
猫(u8),
}
现在我有一个将此类型作为参数的函数。我知道(由于某种原因)输入始终是 Cat
。我想实现这一点:
fn count_legs_of_cat(animal:Animal) - > u8 {
如果让Animal :: Cat(c)= animal {c} else {unreachable!()}
}
我可以写这个更短和/或更多的惯用语?
不是真的。我看到的是为每个枚举变体引入一个新的 struct
,然后枚举枚举的方法:
struct Dog(i32);
struct Cat(u8);
enum动物{
狗(狗),
猫(猫),
}
impl动物{
fn猫(自) - >猫{
如果让Animal :: Cat(c)= self {c} else {panic!(Not a cat)}
}
fn dog(self) - >狗{
如果让Animal :: Dog(d)= self {d} else {panic!(Not a dog)}
}
}
//或者更好地说猫?
fn count_legs_of_cat(c:Cat) - > u8 {
c.0
}
当然,你不需要结构,你可以返回 u8
,但可能会很难跟踪。
然而,将来有一丝更好的支持。我认为是高效代码重用RFC ,但更好地描述在博客文章虚拟结构第3部分:将枚举和结构化在一起。该建议将允许 Animal :: Cat
成为独立类型,因此您的方法可以接受 Animal :: Cat
而不必担心。
个人而言,我几乎总是喜欢在我固有的实施并强制呼叫者惊慌:
impl动物{
fn cat(self) - >选项<目录> {
如果让Animal :: Cat(c)= self {
Some(c)
} else {
无
}
}
fn dog(self) - >选项<狗和GT; {
如果让Animal :: Dog(d)= self {
Some(d)
} else {
无
}
}
}
我可能会使用匹配
impl动物{
fn cat(self) - >选项<目录> {
match self {
Animal :: Cat(c)=>一些(c),
_ =>没有,
}
}
fn dog(self) - >选项<狗和GT; {
match self {
Animal :: Dog(d)=>一些(d),
_ =>没有,
}
}
}
I have this enum type:
enum Animal {
Dog(i32),
Cat(u8),
}
Now I have a function that takes this type as parameter. I know (for some reason) that the input is always a Cat
. I want to achieve this:
fn count_legs_of_cat(animal: Animal) -> u8 {
if let Animal::Cat(c) = animal { c } else { unreachable!() }
}
Can I write this shorter and/or more idiomatic?
Not really. What I have seen is introducing a new struct
for each enum variant, and then methods on the enum to decompose it:
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
}
Of course, you don't need the struct and you could just return the u8
, but that may get hard to track.
There's a glimmer of better support for this in the future, however. I think it's the "efficient code reuse" RFC, but better described in the blog post Virtual Structs Part 3: Bringing Enums and Structs Together. The proposal would be to allow Animal::Cat
to be a standalone type, thus your method could accept an Animal::Cat
and not have to worry about it.
Personally, I almost always prefer to write the infallible code in my inherent implementation and force the caller to panic:
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
}
}
}
And I'd probably use a 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,
}
}
}
这篇关于枚举变体已知时解开内部类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!