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
-运算符)。