rust 用于匹配内嵌查找的特定标识符的宏

5kgi1eie  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(148)

好的,我在Rust中写了我的第一个项目。所以,我有类似下面的设置:

use phf;
use std::str;

struct Values {
  a: Option<char>,
  b: Option<char>,
  c: Option<char>
}

static MAPPING: phf::Map<&'static str, Values> = phf::phf_map! {
  "some_key" => Values {
    a: Some('a'),
    b: Some('b'),
    c: None
  },

  "some_other_key" => Values {
    a: Some('1'),
    b: None,
    c: None
  },

  "some_third_key" => Values {
    a: None,
    b: Some('x'),
    c: Some('y')
  }
}

static NULL_VALUES: Values = Values {
  a: None,
  b: None,
  c: None
}

// Should return a &str for any given key/val

# [macro_export]

macro_rules! get_value {
  ($key: ident, $val: ident) => {{
    use crate::values::MAPPING;
    use std::str;
    let result = MAPPING.get("$key");
    if let Some(r) = result {
      if let Some(c) = r.$val {
        if let Ok(s) = str::from_utf8(%[c as u8]) { s } else { "" }
      } else { "" }
    } else { "" }
  }}
}

它 * 工作 *,但它只是这么多的代码,似乎是一个整体的大量运行时开销没有其他原因,只是组织一些静态值,以避免记住他们所有(实际上有很多,而且都是原始代码点)。我希望能够有一个宏,它接受一个特定的key/瓦尔,并简单地内联一个已知值或空值,但据我所知,没有任何方法可以在一个 specific 标识符上匹配宏,只有 any 标识符......是否有任何方法可以将所有这些查找从运行时转移到编译时?

e4eetjau

e4eetjau1#

宏可以对特定的标识符进行模式匹配--只是不要使用$

macro_rules! get_value {
    (some_key, a) => { Some('a') };
    (some_key, b) => { Some('b') };
    (some_key, c) => { None };
    (some_other_key, a) => { Some(1) };
    // ...
}

但是,您确定不想定义一组const蚂蚁吗?

const SOME_KEY_A: Option<char> = Some('a');
const SOME_KEY_B: Option<char> = Some('b');

或者公开您已经设计好的Values结构体,然后像SOME_KEY.a一样访问它:

const SOME_KEY: Values = Values {
    a: Some('a'),
    b: Some('b'),
    c: None
};

这样,读者不必了解宏就知道数据只是一个常量。这将使代码更易于阅读和修改。

相关问题