是否有可能编写可用于自动管理D中函数的模板或类似文件?手动写出所有嵌套的委托人会杀死我。
基本上,对于具有[ 3个参数,通常可以像f
一样调用,我希望它可以像f(a,b,c)
那样调用。
我知道f(a)(b)(c)
,但这不是我想要的。我想翻译函数定义端,而不是调用端。
我也知道这不是最佳实践,但是我正在生成代码,所以请多多包涵。
嗯,遵循这些原则应该可以完成这项工作:
std.functional.partial
这个想法很简单:根据剩余的参数生成辅助函数-如果有的话,返回该辅助对象的地址作为委托,否则,只需返回调用收集的参数的委托即可。一点递归处理1+ arg情况,而静态if则通过返回原始函数处理0 arg情况。
要注意的语言功能:
同名模板。如果模板的成员与模板具有相同的名称(在本例中为autocurry),则在使用时会自动对其进行引用。
元组扩展。当我调用template autocurry(alias what) {
import std.traits;
static if(Parameters!what.length)
auto autocurry(Parameters!what[0] arg) {
alias Remainder = Parameters!what[1 .. $];
auto dg = delegate(Remainder args) {
return what(arg, args);
};
static if(Remainder.length > 1)
return &autocurry!dg;
else
return dg;
}
else
alias autocurry = what;
}
int foo(int a, string b, float c) {
import std.stdio; writeln(a, " ", b, " ", c);
return 42;
}
string test() {
import std.stdio; writeln("called test");
return "no args";
}
void main() {
import std.stdio;
alias lol = autocurry!foo;
writeln(lol(30)("lol")(5.3));
auto partial = lol(20);
partial("wtf")(10.5);
alias t = autocurry!test;
writeln(t());
}
时,作为内置元组的what(arg, args)
将自动展开以创建完整的参数列表。
此处各种自动返回(显式args
和隐式auto autocurry
关键字,未指定返回类型)仅转发主体碰巧返回的任何其他随机类型。
在主函数中,我执行了delegate
(我经常使用lol作为占位符名称,哈哈)。您也可以在顶级对其进行重载:
alias lol = autocurry!foo;
现在您可以直接在原件旁边使用它:
int foo(int a, string b, float c) {
import std.stdio; writeln(a, " ", b, " ", c);
return 42;
}
alias foo = autocurry!foo; // overloads the auto-curried foo with the original foo
如果您希望使用新名称,或者过载由您自己决定,则两者都可以使用。
请注意,每个参数都有可能分配一些内存来存储给下一个委托。 GC将负责清理。