我在程序的一个模块中有一个全局项目列表(每个项目都有几个属性)。它是不可变的,并且在代码中是静态定义的,所以不用担心。
例如,假设我有蔬菜,它只是一个别名,用name (字符串)、code (ubyte)和price (ushort)将它们定义为一个不可变的元组。
我希望能够通过name或code访问这些蔬菜,所以我认为既然蔬菜列表在编译时是已知的,那么我可以使用对这些蔬菜的引用(比如string=>vegetable和ubyte=>vegetable)来构造关联数组。
这就是我想要实现的东西:
static struct instructions
{
// list of Veggies
immutable instr[] list = [
Veggie("Potato" , 0xD0, 2),
Veggie("Carrot" , 0xFE, 5),
];
// genByCode and genByName being pure functions that get CTFE'd
// and return the desired associative array
immutable instr[ubyte] byCode = genByCode(list);
immutable instr[string] byName = genByName(list);
// overloaded function returns the right Veggie
instr get(string name) const
{ return byName[name]; }
instr get(ubyte code) const
{ return byCode[code]; }
}使用以下形式的生成器函数(为清楚起见将其分开)
pure instr[ubyte] genByCode(immutable Veggie[] list)
{
instr[ubyte] res;
foreach (i ; list)
res[i.code] = i;
return res;
}我花了相当多的时间胡闹,但我不能去工作。当然,在运行时构造它是微不足道的,但显然它应该可以在编译时完成。
一开始我认为这是一个可变性的问题,所以我尝试将所有东西(蔬菜和蔬菜列表)标记为不可变的(因为它们本来就应该是不可变的),但后来我遇到了我认为是不可变的元组的问题,感觉太迷茫了,无法继续下去。
我可以从一个对这里的机制有更清晰的概述的人那里得到帮助吗?谢谢!
发布于 2018-12-02 04:38:37
数据已经存在,不需要构造编译时关联数组。
只需静态地迭代它:
static auto get(int code)(){
static foreach(veggie; list)
static if(veggie.code == code)
return veggie;
}
...
void main(){
writeln(instructions.get!0xD0);
}它可能比通过散列映射进行访问慢,但这就是CTFE的生命周期。
要确保它在编译时求值,可以使用以下命令:
template get(int code){
static foreach(veggie; list)
static if(veggie.code == code)
alias get = veggie;
}https://stackoverflow.com/questions/53522023
复制相似问题