gpt4 book ai didi

D:使用带有名称的字符串变量调用函数

转载 作者:行者123 更新时间:2023-12-04 09:30:44 25 4
gpt4 key购买 nike

D 学习者在这里...如果我有一个字符串(仅在运行时知道的值)是我要调用的函数的名称,我该怎么做?下面的例子...

void func001() {
//stuff
}

void func002() {
//stuff
}

// .........

void func100() {
//stuff
}

void main(char[][] args) {
auto funcnum = to!uint(args[0]);
auto funcname = format('func%03d', funcnum);
///// need to run the function named 'funcname' here
}

最佳答案

这是一个使用编译时反射的示例。与 __traits(allMembers) ,我们可以遍历聚合中所有成员的名称(模块、结构、类等),并使用 __traits(getMember) ,我们可以按名称获取成员并执行诸如调用它之类的操作。

棘手的部分是getMember需要一个编译时间字符串,所以我们不能直接将命令行参数传递给它。相反,我们构建一个 switch从参数中分派(dispatch) - 几乎就像您手动一样,但不是自己编写所有名称,而是让循环处理它。

这里只有两个函数,但它可以扩展到任意数量而无需修改 main功能。

查看更多内联评论:

import std.stdio;

// I'm grouping all the commands in a struct
// so it is easier to loop over them without
// other stuff getting in the way
struct Commands {
// making them all static so we don't need to instantiate it
// to call commands. This is often not the best way but it makes
// for an easy demo and does work well a lot of the time.
static:

// Also assuming they all return void and have no arguments.
// It is possible to handle other things, but it gets a lot
// more involved. (I think my book example goes partially into
// it, or something like my web.d goes all the way and generates
// web/http and javascript/json apis from a full signature but that
// code is pretty unreadable...)

void func001() {
writef("func001 called\n");
}
void func002() {
writef("func002 called\n");
}
}

void main(string[] args) {
if(args.length > 1)
// we switch on the runtime value..
// the label will be used below
outer: switch(args[1]) {
// then loop through the compile time options to build
// the cases. foreach with a compile time argument works
// a bit differently than runtime - it is possible to build
// switch cases with it.
//
// See also: http://dlang.org/traits.html#allMembers
// and the sample chapter of my book
foreach(memberName; __traits(allMembers, Commands)) {
case memberName:
// get the member by name with reflection,
// and call it with the parenthesis at the end
__traits(getMember, Commands, memberName)();

// breaking from the labeled switch so we don't fallthrough
// and also won't break the inner loop, which we don't want.
break outer;
}

default: // default is required on most D switches
writef("No such function, %s!\n", args[1]);
break;
}
else { // insufficient args given
writeln("Argument required. Options are:");
// we can also loop to list names at runtime
foreach(memberName; __traits(allMembers, Commands)) {
writeln(memberName);
}
}
}

关于D:使用带有名称的字符串变量调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31993705/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com