16个版本 (6个稳定版)
1.5.0 | 2024年5月26日 |
---|---|
0.10.0 | 2024年2月19日 |
0.7.0 | 2023年2月6日 |
0.4.0 | 2022年12月30日 |
#240 在 数据结构 中
95 每月下载
32KB
284 行
EnumMap for Rust
枚举变体到值的映射。EnumMap 是一个固定大小的映射,其中每个枚举变体映射到一个值。此 EnumMap 实现使用 安全 Rust 且作为数组(固定大小)的抽象,数组的索引对应于枚举变体的位置。
因为它是数组的包装,所以默认情况下是堆栈分配的。简单地通过 std::boxed::Box
调用它将使其移动到堆上,由调用者决定。
- 通过枚举变体索引。
- 通过枚举变体索引。
- 如果枚举是 Debug,则进行调试。
- 如果值是 PartialEq,则进行 PartialEq。对于 Eq 也是如此。
Debug 和 Eq 是可选功能。默认情况下是启用的。
用法
请参阅 文档 以获取功能列表和更深入的文档。
use enum_collections::{EnumMap, Enumerated, em, em_default, em_option};
#[derive(Enumerated)]
pub enum Letter {
A,
B,
}
// Indexing and mutation
// The SIZE hint is required until [generic_const_expr](https://github.com/rust-lang/rust/issues/76560) are stabilized.
let mut enum_map = EnumMap::<Letter, i32, { Letter::SIZE }>::new_default();
assert_eq!(0, enum_map[Letter::A]);
enum_map[Letter::A] = 42;
assert_eq!(42, enum_map[Letter::A]);
// Construction using macros
// (Key type, Value type, Key=>Value pairs)
let enum_map = em!(Letter, i32, A=>42, B=>24); // All values set explicitly
assert_eq!(42, enum_map[Letter::A]);
assert_eq!(24, enum_map[Letter::B]);
// (Key type, Value type, optional Key=>Value pairs)
let enum_map = em_default!(Letter, i32, A => 42); // Default used for missing values
assert_eq!(42, enum_map[Letter::A]);
assert_eq!(i32::default(), enum_map[Letter::B]);
let enum_map = em_default!(Letter, i32,); // All default
assert_eq!(i32::default(), enum_map[Letter::A]);
assert_eq!(i32::default(), enum_map[Letter::B]);
// EnumMap of optional values `Option<V>`, value type is automatically wrapped in `Option`.
// (Key type, Value type, optional Key=>Value pairs)
let enum_map = em_option!(Letter, i32, A => 42);
assert_eq!(Some(42), enum_map[Letter::A]);
assert_eq!(None, enum_map[Letter::B]);
// Constructor with default values
let enum_map_default = EnumMap::<Letter, i32, { Letter::SIZE }>::new_default();
assert_eq!(0, enum_map_default[Letter::A]);
assert_eq!(0, enum_map_default[Letter::B]);
// Convenience constructor for optional values
let mut enum_map_option = EnumMap::<Letter, Option<i32>, { Letter::SIZE }>::new_option();
assert_eq!(None, enum_map_option[Letter::A]);
assert_eq!(None, enum_map_option[Letter::B]);
enum_map_option[Letter::A] = Some(42);
assert_eq!(Some(42), enum_map_option[Letter::A]);
// Constructor with custom initialization
#[derive(PartialEq, Eq, Debug)]
struct Custom;
let enum_map = EnumMap::<Letter, Custom, { Letter::SIZE }>::new(|| Custom);
assert_eq!(Custom, enum_map[Letter::A]);
assert_eq!(Custom, enum_map[Letter::B]);
// Custom initialization function with enum variant (key) inspection
let enum_map = EnumMap::<Letter, i32, { Letter::SIZE }>::new_inspect(|letter| {
match letter {
Letter::A => 42,
Letter::B => 24,
}
});
assert_eq!(42, enum_map[Letter::A]);
assert_eq!(24, enum_map[Letter::B]);
// Debug
#[derive(Enumerated, Debug)]
pub enum LetterDebugDerived {
A,
B,
}
let enum_map_debug =
EnumMap::<LetterDebugDerived, i32, { LetterDebugDerived::SIZE }>::new(|| 42);
assert_eq!("{A: 42, B: 42}", format!("{:?}", enum_map_debug));
迭代枚举变体
#[derive(Enumerated, Debug)]
pub enum Letter {
A,
B,
}
Letter::VARIANTS
.iter()
.for_each(|letter| println!("{:?}", letter));
功能
功能部分是功能标志的,但默认启用。这是为了在不需要时关闭此功能,例如 Debug
和 Eq
实现。有关详细信息,请参阅 docs.rs。
基准测试
使用 cargo bench
运行基准测试。虽然 EnumMap
在皮秒内运行,但 std::collections::HashMap
在 10 纳秒以上。
基准测试结果
EnumMap get time: [221.09 ps 221.59 ps 222.21 ps]
Found 10 outliers among 100 measurements (10.00%)
5 (5.00%) high mild
5 (5.00%) high severe
EnumMap insert time: [230.05 ps 233.38 ps 236.25 ps]
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) high mild
1 (1.00%) high severe
EnumMap new: default time: [852.31 ps 853.28 ps 854.37 ps]
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) low mild
1 (1.00%) high mild
EnumMap new: Option::None
time: [1.7100 ns 1.7110 ns 1.7120 ns]
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) high mild
1 (1.00%) high severe
EnumMap new: provider fn
time: [791.17 ps 792.38 ps 793.65 ps]
Found 7 outliers among 100 measurements (7.00%)
1 (1.00%) low mild
4 (4.00%) high mild
2 (2.00%) high severe
EnumMap new: inspecting provider fn
time: [775.03 ps 776.84 ps 778.92 ps]
Found 8 outliers among 100 measurements (8.00%)
4 (4.00%) high mild
4 (4.00%) high severe
std::collections::HashMap get
time: [13.433 ns 13.484 ns 13.543 ns]
Found 8 outliers among 100 measurements (8.00%)
3 (3.00%) high mild
5 (5.00%) high severe
std::collections::HashMap insert
time: [14.094 ns 14.107 ns 14.121 ns]
Found 4 outliers among 100 measurements (4.00%)
1 (1.00%) high mild
3 (3.00%) high severe
依赖关系
~1.5MB
~34K SLoC