为什么std :: i64 :: MIN .. =-1i64和`1i64 .. = std :: i64 :: MAX`不在我的模式中?

问题描述 投票:1回答:2

如何将i64变量与正,零和负模式匹配?

说我有以下函数f1,我想进行匹配,对于负输入,返回-1,对于正输入,返回1,对于0,返回0。

fn f1(value: i64) -> i64 {
    match value {
        num if num > 0 => 1,
        0 => 0,
        num if num < 0 => -1,
    }
}

#[test]
fn test_f1() {
    assert_eq!(f1(-5), -1);
}

游乐场链接为here

但是它抱怨“错误[E0004]:非穷尽模式:std::i64::MIN..=-1i641i64..=std::i64::MAX未涵盖”。正确的模式是什么?

随时建议更好的方式来编写模式,我希望将其写在如下范围内:

fn f1(value: i64) -> i64 {
    match value {
        1.. => 1,
        0 => 0,
        ..=-1 => -1,
    }
}

但是即使我每晚启用,它仍然建议“将#![feature(exclusive_range_pattern)]添加到要启用的板条箱属性”,但我不确定如何在Playground中执行此操作。

rust
2个回答
2
投票

对于普通花纹,铁锈可以检查火柴臂是否完整。这是因为普通模式的形式很少,所有锈都已被告知如何理解。

但是您的比赛武器涉及if条件,在这种情况下有时也称为守卫。守卫中的条件可以具有任意形式。有些看起来很简单,但是othersarehard。包括rust在内的任何编译器都无法预测任意条件。这是一个mathematical fact。因此,生锈不会浪费时间。

在这种情况下,实际上有一种方法可以将护罩换成普通的图案,这样可以彻底检查锈迹。

fn f1(value: i64) -> i64 {
    match value {
        1..=std::i64::MAX => 1,
        0 => 0,
        std::i64::MIN..=-1 => -1,
    }
}

您可以使用半开范围,但是它们需要不稳定的生锈。

fn f1(value: i64) -> i64 {
    match value {
        1.. => 1,
        0 => 0,
        ..=-1 => -1,
    }
}

1
投票

如果您的目标是尽可能简单地编写f1,则已经有一个函数,它叫做i64::signum

fn sign(x: i64) {
    println!("sign of {} is {}", x, x.signum());
}

fn main() {
    sign(-10);
    sign(0);
    sign(10);
}

如果您的目标是更一般地编写符号比较以执行其他操作,则可以这样编写:

fn sign(x: i64) {
    match x.signum() {
        -1 => println!("negative"),
        0 => println!("zero"),
        1 => println!("positive"),
        _ => unreachable!(),
    }
}

编译器通常可以合理地优化此代码。

© www.soinside.com 2019 - 2024. All rights reserved.