如何获取枚举中元素(变体)的数量作为常量值? [英] How to get the number of elements (variants) in an enum as a constant value?

查看:27
本文介绍了如何获取枚举中元素(变体)的数量作为常量值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is there a way to extract the number of elements in an enum?

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

Simple example (with imaginary number_of_elements method):

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

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

在 C 中,我通常会...

In C I'd normally do...

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

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

However the Rust equivalent to this doesn't work:

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

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

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

Including the last item in the enum is very inconvenient because matching enums will error if all members aren't accounted for.

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

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

Is there a way to get the number of items in an enum as a constant value?

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

Note: even though this isn't directly related to the question, the reason I was wanting this feature is I'm using the builder-pattern to construct a series of actions which only make sense to run once. For this reason I can use a fixed size array the size of the enum.

推荐答案

您可以使用 程序宏:

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()
}

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

It is left as an excercise to the reader to ensure that this derive macro can be used multiple times within the same module.

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

To use the macro, just attach #[derive(EnumVariantCount)] to your enum. There should now be a global constant named LENGTH.

这篇关于如何获取枚举中元素(变体)的数量作为常量值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆