如果我想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
)替换为_
?
答案 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)]
的枚举......但是有一些箱子似乎让它变得更容易。
在此特定情况中,您还可以生成随机布尔值,然后选择1
或2
:
if rand::thread_rng().gen() {
println!("1")
} else {
println!("2")
}