fre*_*esh 4 pattern-matching rust
我有以下 Rust 代码的问题:
pub fn median(v: &Vec<i32>) -> f32 {
let len = v.len();
match len % 2 {
0 => (v[len / 2 - 1] + v[len / 2]) as f32 / 2 as f32,
1 => v[(len - 1) / 2] as f32,
}
}
Run Code Online (Sandbox Code Playgroud)
由于“非详尽模式”错误,此代码无法编译。这是为什么?% 运算符返回什么?
最简单的修复方法是使用_而不是1:
match len % 2 {
0 => (v[len / 2 - 1] + v[len / 2]) as f32 / 2 as f32,
_ => v[(len - 1) / 2] as f32,
}
Run Code Online (Sandbox Code Playgroud)
因为len在第二个分支中 是奇数且非负,(len - 1) / 2因此与 相同len / 2。我会像这样简化它:
let mid = v.len() / 2;
match v.len() % 2 {
0 => (v[mid - 1] + v[mid]) as f32 / 2.0,
_ => v[mid] as f32,
}
Run Code Online (Sandbox Code Playgroud)
编译器不够聪明,无法确定 的结果len % 2只能是0或1。对于结果为其他值的情况,它需要匹配臂。您可以通过明确说明这些情况是不可能的来解决这个问题:
match len % 2 {
0 => (v[len / 2 - 1] + v[len / 2]) as f32 / 2 as f32,
1 => v[(len - 1) / 2] as f32,
_ => unreachable!()
}
Run Code Online (Sandbox Code Playgroud)
在_将匹配前面没有提到任何其他值。该unreachable!()告诉编译器“这个代码将不会执行”,但会导致panic!()以防万一它实际上执行。这样,该程序始终是正确的,几乎没有成本。
编译器的未来版本可能会发现这些值2..或不可能。
该%是remainder operator(不与被共熔mod-运算符)。