如何在匹配语句中使用 const 范围?

pur*_*tii 8 pattern-matching rust

这有效:

match 0 {
    0..=9 => (),
    _ => (),
}
Run Code Online (Sandbox Code Playgroud)

但这并没有:

const R: std::ops::RangeInclusive<u8> = 0..=9;

fn main() {
    match 0 {
        R => (),
        _ => (),
    }
}
Run Code Online (Sandbox Code Playgroud)

游乐场

如果我想将范围与 一起使用match,我必须使用文字范围吗?

phi*_*mue 5

我认为问题在于,当您match使用时,每个匹配臂都必须提供可以与参数进行比较的u8类型值。u8

现在,如果您编写0..=9,这不是 a RangeInclusive(即使它看起来相同) - 它是一个范围模式,可用于描述匹配臂中的一系列值。

因此,如果您R => ()在匹配臂中编写,编译器会抱怨(在我看来是正确的):

error[E0308]: mismatched types
 --> src/main.rs:7:9
  |
7 |         R => (),
  |         ^ expected integer, found struct `std::ops::RangeInclusive`
  |
  = note: expected type `u8`
             found type `std::ops::RangeInclusive<u8>`
Run Code Online (Sandbox Code Playgroud)

即它需要一个u8(或者隐式地,u8值的范围模式),但它发现了一个RangeInclusive.

现在,一种可能的解决方案是将下限和上限定义为单独的常量:

const LOWER : u8 = 0;
const UPPER : u8 = 9;
const R: std::ops::RangeInclusive<u8> = LOWER..=UPPER; // <- this is a RangeInclusive<u8>

fn main() {
    match 0 {
        LOWER..=UPPER => (), // <- this is a range pattern
        _ => (),
    }
}
Run Code Online (Sandbox Code Playgroud)

在我看来,另一种不太吸引人的方法是一个仅扩展到您的范围的宏:

macro_rules! myrng{() => {0..=9}}
const R: std::ops::RangeInclusive<u8> = myrng!();

fn main() {
    match 0 {
        myrng!() => (),
        _ => (),
    }
}
Run Code Online (Sandbox Code Playgroud)