如何为特征的每个实现自动生成递增的数字标识符?

Posted

技术标签:

【中文标题】如何为特征的每个实现自动生成递增的数字标识符?【英文标题】:How to automatically generate incrementing number identifiers for each implementation of a trait? 【发布时间】:2019-01-05 17:42:33 【问题描述】:

我有一个 Component 特征,它有一个返回索引的方法,如下所示:

trait Component 
    fn index(&self) -> usize;

这些索引用于设置位集中的标志。例如,返回索引 5 的 Component 特征对象将导致在容器中设置第 5 位。

目前我手动返回每个实现类型的运行索引:

struct Foo;
struct Bar;

impl Component for Foo 
    fn index(&self) -> usize  0 


impl Component for Bar 
    fn index(&self) -> usize  1 

特征对象被插入到一个容器中,该容器使用位集跟踪添加的组件:

struct Container<'a> 
    components: Vec<Component + 'a>,
    bits: BitSet


impl<'a> Container<'a> 
    fn add<T: Component + 'a>(&mut self, component: T) 
        self.components.push(component);
        self.bits.set(component.index());
    

这很好用,但是手动返回每个实现类型的索引很麻烦。我怎样才能让每个实现类型都能自动获取它的索引?

【问题讨论】:

我对您的问题一无所知,但请查看bitfield 或sparse_bitfield @Stargateur 我真的不明白这与我的问题有什么关系?我已经有了自己的、正常工作的 bitset 实现。 哦,我想更多的是 bitflags 抱歉。但是我仍然不明白您要做什么,您正在显示手动实现两种类型的值的代码,这对我来说真的不像是强大的代码,您目前唯一的答案是构建一个宏,您的问题没有包含足够的上下文来理解您在做什么。 @Stargateur 我想用宏或其他自动生成索引的东西替换手动值检索。 【参考方案1】:

你可以定义一个递归调用自身的宏:

macro_rules! impl_component 
    // Empty case to end the recursion
    ($n:expr ;) => ;
    // Match the current count, the current type, and whatever else comes after
    ($n:expr ; $t:ty $(, $rest:tt)*) => 
        impl Component for $t 
            fn index(&self) -> usize  $n 
        
        // Recurse, incrementing counter and only passing the remaining params
        impl_component!($n + 1; $($rest),*);
    ;
    // For the first recursion, set the counter initial value to zero
    ($($types:tt),+) =>  impl_component!(0; $($types),*); ;


impl_component!(Foo, Bar, Baz);

生成的代码将包含如下实现:

impl Component for Baz 
    fn index(&self) -> usize  0 + 1 + 1 

编译器会将这些表达式折叠成文字,因此结果与您想要的一样。

【讨论】:

以上是关于如何为特征的每个实现自动生成递增的数字标识符?的主要内容,如果未能解决你的问题,请参考以下文章

在excel中怎样使一个长数字,如30778287700实现自动递增?

如何从某个数字(如 2456)启动 Django 模型自动递增键?

如何在 SQL SERVER 2008 中启用字母自动递增(A、B、C、D ...)?

如何为平板电脑上的输入字段自动打开数字键盘?

如何为每个 AMI/EBS 设置自动计划快照?

如何为每个商店自动增加特定的数据库表值。 (Laravel 6)