如何为特征的每个实现自动生成递增的数字标识符?
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 模型自动递增键?