我可以在与gen_range匹配的模式中避免使用`_`吗?

时间:2017-05-17 13:11:46

标签: rust

如果我想match rand::thread_rng().get_range(1, 3)的结果,我需要添加_值,即使知道只有两个可能的值:

match rand::thread_rng().gen_range(1, 3) {
    1 => println!("1"),
    2 => println!("2"),
    _ => panic!("never happens")
};

_案例无用但需要。

我理解编译器不能猜测gen_range(1, 3)只能返回1或2但是有一种方法可以避免添加这个无用的行_ => panic!("never happens")和模式匹配(可能有一些提示编译器)?或者我是否需要将最后一个值(2)替换为_

1 个答案:

答案 0 :(得分:6)

  

我理解编译器无法猜测gen_range(1, 3)只能返回1或2

这是正确的。在这种情况下,gen_range会返回i32,而i32可能会有更多值。

  

有没有办法避免添加这个无用的行_ => panic!("never happens")

正如评论中所述,unreachable!更好地表达了您的意图,而不仅仅是简单panic!

match rand::thread_rng().gen_range(1, 3) {
    1 => println!("1"),
    2 => println!("2"),
    _ => unreachable!(),
};
  

将最后一个值(2)替换为_

这没关系,但是"失败"最终更改参数的情况可能更难以发现:

match rand::thread_rng().gen_range(1, 100) {
    1 => println!("1"),
    _ => println!("2"), // oops!
};

在测试过程中恐慌的版本更容易爆炸。您选择哪种方式取决于您和您的风险承受能力。

  

唯一的"防弹"替代方案是使用enum { One, Two },但它会导致更多的样板,并且只是稍微强制进行范围检查

这很有用,如果您想在代码中多次使用match,那将非常有用。这将逻辑合并到一个位置。

我有点惊讶的是,没有一个宏的1.1 crate允许类似于#[derive(Rand)]的枚举......但是有一些箱子似乎让它变得更容易。

此特定情况中,您还可以生成随机布尔值,然后选择12

if rand::thread_rng().gen() {
    println!("1")
} else {
    println!("2")
}