我想创建一个类似于编译时不可变Map的结构,在编译时安全地检查键,更一般地说,我想创建一个具有安全键访问的可迭代关联数组。
我的第一次尝试是使用const HashMap
(如所描述的here),但密钥无法安全访问:
use phf::{phf_map};
static COUNTRIES: phf::Map<&'static str, &'static str> = phf_map! {
"US" => "United States",
"UK" => "United Kingdom",
};
COUNTRIES.get("EU") // no compile-time error
我考虑的另一个选项是对strum
crate使用可枚举枚举枚举,如here所述:
use strum::IntoEnumIterator; // 0.17.1
use strum_macros::EnumIter; // 0.17.1
#[derive(Debug, EnumIter)]
enum Direction {
NORTH,
SOUTH,
EAST,
WEST,
}
fn main() {
for direction in Direction::iter() {
println!("{:?}", direction);
}
}
除了rust中的enum
值只能是整数之外,这是可以实现的。要分配一个不同的值,需要类似于用match
语句实现枚举的value()
函数。(例如所描述的here),然而这意味着每当开发人员决定附加新项时,value
函数也必须被更新,并且每次在两个地方重写枚举名并不理想。
我最后一次尝试是在impl
中使用const
s,如下所示:
struct MyType {
value: &'static str
}
impl MyType {
const ONE: MyType = MyType { value: "one" };
const TWO: MyType = MyType { value: "two" };
}
这允许单写实现,并且对象是安全可访问的编译时常量,但是我发现没有办法迭代它们(如变通方法here所示)(尽管这可能是某种过程宏的可能)。
我来自很多TypeScript,在那里这种任务非常简单:
const values = {
one: "one",
two: "two" // easy property addition
}
values.three; // COMPILE-TIME error
Object.keys(values).forEach(key => {...}) // iteration
或者甚至在Java中,这可以简单地通过带有属性的enums
来完成。
我知道这听起来有点像XY问题,但我并不认为这是一件荒谬的事情,通常要求一个 * 安全,可迭代,编译时不可变常量关联数组 *(天哪,这是不是有点拗口)。这种模式在Rust中可能吗?事实上,我在上面找不到任何东西,而且它看起来很难,这让我相信我所做的不是Rust代码的最佳实践。在这种情况下,有什么替代方案呢?如果这对Rust来说是一个糟糕的设计模式,那么什么会是一个好的替代方案呢?
1条答案
按热度按时间gcxthw6b1#
@JakubDóka我该如何实现它?我看了一些过程宏,但似乎不明白如何实现这样的宏。