在 Rust 中,假设我有一个枚举,我想根据它的变体和一些涉及它的值的测试做一些有条件的事情。我很难找到写这个的好方法。
例如,假设我有一个枚举来表示农场动物,变体给出了它们的物种,而值给出了一些其他属性,例如它们的重量。
enum Animal {
Horse(i32),
Cow(i32, i32),
Sheep,
// and so on
}
我想要一个喂养动物的功能。大多数动物都吃干草,但体重低于 700 公斤的马却吃胡萝卜。直觉上我想写
fn feed(animal: Animal) {
if let Animal::Horse(weight) = animal && weight < 700 { // ferris_is_confused.png
// feed carrots
} else {
// feed hay
}
}
但我收到编译错误“let
这个位置的表达式是实验性的”和“预期的表达式,找到的语句(let
)”。我可以写
fn feed(animal: Animal) {
if let Animal::Horse(weight) = animal {
if weight < 700 {
// feed carrots
} else {
// feed hay
}
} else {
// feed hay
}
}
但后来我必须复制 // feed hay
代码,如果它很长或经常更改,则可能会出现问题。如果我使用
match
,我也有同样的问题: 我可以做个测试if weight < 700
内Horse
arm,但后来我又必须包括 // feed hay
在其 else
以及在 _
ARM 。是否有一种标准的惯用方式来编写它而不复制代码?这可能是一个常见问题,但我可能正在搜索错误的术语。
我正在使用 rustc 1.46.0。
最佳答案
Match guards已经存在了一段时间(Debian buster 的 1.34.2 已经有了它们)并以不那么冗长的方式支持这个用例:
fn feed(animal: Animal) {
match animal {
Animal::Horse(weight) if weight < 700 => {
// feed carrots
}
_ => {
// feed hay
}
}
}
或者,您可以将饲料干草部分移动到本地函数中并从多个地方调用它。
关于enums - 如何结合枚举变量和值的测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63781920/