原文 今天,我有一堆带有执行某些操作的参数的函数,我想通过程序的命令行向用户公开他们.此外,为了尽量方便用户,程序帮助文本应准确地描述每个函数(在命令行上被视为子命令)及每个函数带的参数.
当然,传统方法很简单:编写打印描述函数及其参数文本的showHelp()函数.然后在main()中为函数名编写大的switch语句,每个case块解析程序参数,转换为合适形式,并调用该显示函数.
因此,我本着DRY寻求了更好方法:把所述函数放入包装结构中,按静态标记它,添加由showHelp()自省的串UDA,来生成保证最新的函数列表,并通过main()生成必要的若块.
帮助文本很简单:只需检查包装器结构,提取函数名,描述串UDA和参数名列表,然后打印出来.
case块有点棘手.如果每个函数有相同参数集,那就很简单了:只需在标准调用中插件函数名即可.但是,如果函数有*不同*参数呢?
然后灵感来了:为什么要单独声明这些变量呢?我不必.我可用is(typeof(func)Params:__parameters)参数元组保存参数,然后按该类型用参数元组声明复合变量:
void main(string[] args) {
...
static if (is(typeof(myfunc) Params : __parameters)) {
Params funcArgs; //为所有函数参数使用一个名字
//现在`转换`命令行参数至正确类型来填充参数
foreach (i, T; Params) {
// std.conv.to是大炸弹
import std.conv : to;
funcArgs[i] = args[i+2].to!T;
}
//要调用函数,只需一次性传递整个聚集给它:
myfunc(funcArgs);
//感谢神奇元组类型,它会自动展开`funcArgs`元组为多个参数
}
}复合变量'funcArgs'具体化了目标函数参数;允许解析命令行参数循环中像伪数组一样操作它.不必构建繁琐参数列表的mixin!(当然,实际代码,仍需要mixin来绑定myfunc到实际按名迭代的目标函数.)
