enums - 如何获取枚举中元素(变体)的数量作为常量值?

标签 enums rust

有没有办法提取枚举中的元素数量?

简单示例(使用虚构的number_of_elements 方法):

enum FooBar { A = 0, B, C, };

println!("Number of items: {}", FooBar.number_of_elements());
// "Number of items: 3"

在 C 中我通常会做...

enum FooBar { A = 0, B, C, };
#define FOOBAR_NUMBER_OF_ITEMS (C + 1)

然而,与此等效的 Rust 不起作用:

enum FooBar { A = 0, B, C, };
const FOOBAR_NUMBER_OF_ITEMS: usize = (C as usize) + 1;

// Raises an error:
//     unimplemented constant expression: enum variants

在枚举中包含最后一项非常不方便,因为如果不考虑所有成员,匹配的枚举将会出错。

enum FooBar { A = 0, B, C, FOOBAR_NUMBER_OF_ITEMS, };

有没有办法将枚举中的项数作为常量值?


注意:尽管这与问题没有直接关系,但我想要此功能的原因是我正在使用 builder-pattern构造一系列只运行一次才有意义的 Action 。出于这个原因,我可以使用枚举大小的固定大小数组。

最佳答案

您可以使用 procedural macros :

extern crate proc_macro;
extern crate syn;
#[macro_use]
extern crate quote;

use proc_macro::TokenStream;

#[proc_macro_derive(EnumVariantCount)]
pub fn derive_enum_variant_count(input: TokenStream) -> TokenStream {
    let syn_item: syn::DeriveInput = syn::parse(input).unwrap();
    let len = match syn_item.data {
        syn::Data::Enum(enum_item) => enum_item.variants.len(),
        _ => panic!("EnumVariantCount only works on Enums"),
    };
    let expanded = quote! {
    const LENGTH: usize = #len;
        };
    expanded.into()
}

留给读者作为练习,以确保可以在同一模块中多次使用此派生宏。

要使用宏,只需将 #[derive(EnumVariantCount)] 附加到您的枚举。现在应该有一个名为 LENGTH 的全局常量。

关于enums - 如何获取枚举中元素(变体)的数量作为常量值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41637978/

相关文章:

sql - Hibernate SQL 转换对于 Enum 字段类型失败

Qt ENUMS - setProperty 隐式转换

枚举的初始化可以自动化吗?

rust - 为什么 `Box::into_raw`不把 `self`作为参数呢?

rust - 如何处理包装在Rc <RefCell <>>中的新型枚举的模式匹配?

c - 为什么枚举值可以有很大的 (>int) 值?

rust - 如何在 Rust 中获取当前平台的行尾字符序列?

rust - 如何声明方法的参数实现特定特征

rust - 如何解决错误 "the precise format of ` Fn`-family traits' type parameters is subject to change”?

Java - 如何使用枚举/工厂模式基于字符串调用相应类的方法