Rust 非穷举模式-匹配表达式

Rust 非穷举模式-匹配表达式,rust,pattern-matching,Rust,Pattern Matching,我对以下防锈代码有疑问: 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, } } pub-fn中间带(v:&Vec)->f32{ 设len=

我对以下防锈代码有疑问:

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,
    }
}
pub-fn中间带(v:&Vec)->f32{
设len=v.len();
匹配len%2{
0=>(v[len/2-1]+v[len/2])作为f32/2作为f32,
1=>v[(len-1)/2]作为f32,
}
}
由于“非穷举模式”错误,此代码无法编译。
为什么呢?%运算符返回什么?

编译器不够聪明,无法判断
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!()
}
将与前面未提及的任何其他值匹配。告诉编译器“此代码永远不会执行”,但会导致
死机!()
以防万一它确实执行了。这样,该程序始终是正确的,几乎没有成本

编译器的未来版本可能会发现值
2..
或不可能


%
是(不能与
mod
-运算符一起使用)。

最简单的修复方法是使用
\uuu
而不是
1

match len % 2 {
    0 => (v[len / 2 - 1] + v[len / 2]) as f32 / 2 as f32,
    _ => v[(len - 1) / 2] as f32,
}
因为
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,
}

len%2==0
并与true和false匹配您也可以这样做,>编译器不够聪明,无法判断len%2的结果只能是0或1。是的。但是类型系统要求匹配臂在整个类型上都是穷举的,即使编译器可以发现它不是必需的。作为一个简短的旁注:在发布模式下,编译器可以检测到只有
0
1
是可能的,因此可以完全删除
分支。