编写宏来创建匹配臂

Wou*_*ter 1 macros rust

我正在基于整数数组创建直方图。下面的代码工作正常,但看起来很糟糕,因为我必须手动编写很多匹配臂。但感觉应该有更好的方法来做到这一点,我认为这种方法是一个宏。你能指出我正确的方向吗?

pub fn make_histogram(array: &[u64]) {
    let mut counts = HashMap::new();
    for value in array.iter() {
        match value {
            1..=2000 => *counts.entry("1-2000").or_insert(0) += 1,
            2001..=4000 => *counts.entry("2001-4000").or_insert(0) += 1,
            4001..=6000 => *counts.entry("4001-6000").or_insert(0) += 1,
            6001..=8000 => *counts.entry("6001-8000").or_insert(0) += 1,
            8001..=10000 => *counts.entry("8001-10000").or_insert(0) += 1,
            10001..=12000 => *counts.entry("10001-12000").or_insert(0) += 1,
            12001..=14000 => *counts.entry("12001-14000").or_insert(0) += 1,
            14001..=16000 => *counts.entry("14001-16000").or_insert(0) += 1,
            16001..=18000 => *counts.entry("16001-18000").or_insert(0) += 1,
            18001..=20000 => *counts.entry("18001-20000").or_insert(0) += 1,
            20001..=22000 => *counts.entry("20001-22000").or_insert(0) += 1,
            22001..=24000 => *counts.entry("22001-24000").or_insert(0) += 1,
            24001..=26000 => *counts.entry("24001-26000").or_insert(0) += 1,
            26001..=28000 => *counts.entry("26001-28000").or_insert(0) += 1,
            28001..=30000 => *counts.entry("28001-30000").or_insert(0) += 1,
            30001..=32000 => *counts.entry("30001-32000").or_insert(0) += 1,
            32001..=34000 => *counts.entry("32001-34000").or_insert(0) += 1,
            34001..=36000 => *counts.entry("34001-36000").or_insert(0) += 1,
            36001..=38000 => *counts.entry("36001-38000").or_insert(0) += 1,
            38001..=40000 => *counts.entry("38001-40000").or_insert(0) += 1,
            40001..=42000 => *counts.entry("40001-42000").or_insert(0) += 1,
            42001..=44000 => *counts.entry("42001-44000").or_insert(0) += 1,
            44001..=46000 => *counts.entry("44001-46000").or_insert(0) += 1,
            46001..=48000 => *counts.entry("46001-48000").or_insert(0) += 1,
            48001..=50000 => *counts.entry("48001-50000").or_insert(0) += 1,
            50001..=52000 => *counts.entry("50001-52000").or_insert(0) += 1,
            52001..=54000 => *counts.entry("52001-54000").or_insert(0) += 1,
            54001..=56000 => *counts.entry("54001-56000").or_insert(0) += 1,
            56001..=58000 => *counts.entry("56001-58000").or_insert(0) += 1,
            58001..=60000 => *counts.entry("58001-60000").or_insert(0) += 1,
            _ => *counts.entry("60001-inf").or_insert(0) += 1,
        }
    }
Run Code Online (Sandbox Code Playgroud)

at5*_*321 5

尽管有标题,但您的问题表明您正在寻找问题的解决方案,不一定需要涉及手臂HashMap或匹配手臂。

如果性能对您很重要,我宁愿考虑使用数组,而不是HashMap. 看来你的步骤是固定的,所以你可以写这样的东西:

use std::cmp;

const STEP_SIZE: u64 = 2_000;
const STEPS_COUNT: usize = 30;

// ...
let mut counts = [0; STEPS_COUNT];
// ...
for value in array {
    let idx = cmp::min(((value - 1) / STEP_SIZE) as usize, STEPS_COUNT-1);
    counts[idx] += 1;
}
Run Code Online (Sandbox Code Playgroud)

您在 as 键中使用的范围字符串HashMap看起来像是您可以在需要时构造的东西。您可以每次(即时)执行此操作,也可以生成一次字符串并缓存它们(例如在Strings 数组中)。