enums - 如何结合枚举变量和值的测试?

标签 enums rust

在 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 < 700Horse 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/

相关文章:

unit-testing - 有没有一种简单的方法可以有条件地启用或忽略 Rust 中的整个测试套件?

function - 结构拥有函数的 Rust 作用域规则

rust - 解决在Rust中的leetcode上打乱数组问题

operating-system - 用 Rust 制作一个可启动的 hello world 程序

c# - 带空格的枚举 .TryParse 不起作用 - C#

java - 是否可以使用Java枚举将字母转换为数字?

c# - C#中的字符串值枚举

java - play framework - 在路由中绑定(bind)枚举

python - 使用 PEP 435 兼容枚举的带有枚举的 SQLAlchemy 列产生表创建错误

loops - 为什么我不能在两个不同的映射函数中可变地借用变量?