我有以下问题。
在输入consol中我可以输入一个字符串,系统会 基于此采取行动。
因此,如果我输入add_2_with_2,如果我输入,它将给我一个4 sqrt_4它会给我2等等。一般来说,你会用一个 switch / case命令,但问题是,那我需要一个 每个案件的条件。所以,如果我想ADITTIONALLY输入 cube_2,然后我必须为此写一个案例。
但是,我想在不必明确的情况下做同样的事情 每次插入新命令时写一个案例。例如,如果 在输入“FUNCTION_1”中,程序应该查看特定的 在特定的forlder /文件中,找出函数是否正确 定义并执行它。如果未在文件/文件夹中定义, 然后它应该抛出一个例外。如果我还想 输入“FUNCTION_2”,然后我将定义相同的功能 文件或文件夹(D可能的任何可能)然后让 原始程序自动搜索和执行。
这可以在D?
完成(对不起愚蠢的问题和糟糕的英语)
答案 0 :(得分:3)
碰巧,我刚做了类似的事情:
https://github.com/schancel/gameserver/blob/master/source/client/messaging.d
代码不是最漂亮的,但它使用反射来插入额外的case语句。
答案 1 :(得分:3)
是的,你可以,有几种方法可以做到。
1)您可以从一个程序内部调用函数,并使用编译时反射自动查找/映射它们。
我在终端模拟器的实用程序中这样做了。查看源代码,了解我是如何做到的: https://github.com/adamdruppe/terminal-emulator/blob/master/utility.d
要将它用于您自己的目的,您可以删除version()语句,更改模块名称并编写自己的函数。
2)您还可以在目录中查找脚本并以这种方式运行它们。使用std.process和std.file查找文件并运行它。
答案 2 :(得分:3)
我认为您正在寻找的内容通常在文献中称为 Command Pattern 。在大量OO语言中,这种模式通常涉及创建一堆类,这些类实现了一个简单的 Command 接口,该接口具有单个execute()
方法。
然而,在D中,你有代表,并且可以避免为此目的生成可能有数百个小类。
这是可能的D替代方案之一,使用lambda表达式(http://dlang.org/expression.html#Lambda):
module command2;
import std.stdio;
import std.conv;
import std.array;
// 2 = binary operation
alias int delegate(int arg1, int arg2) Command2;
// Global AA to hold all commands
Command2[string] commands;
// WARNING: assumes perfect string as input!!
void execute(string arg) {
auto pieces = split(arg);
int first = to!int(pieces[1]);
int second = to!int(pieces[2]);
Command2 cmd = commands[pieces[0]];
int result = cmd(first, second); // notice we do not need a big switch here
writeln(arg, " --> ", result);
} // execute() function
void main(string[] args) {
commands["add"] = (int a, int b) => a + b;
commands["sub"] = (int a, int b) => a - b;
commands["sqrt"] = (int a, int b) => a * a; // second parameter ignored
// ... add more commands (or better call them operations) here...
execute("add 2 2");
execute("sqrt 4 0"); // had to have 0 here because execute assumes perfect imput
} // main() function
以下是分叉和播放的源代码:http://dpaste.dzfl.pl/41d72036
当我找到更多时间时,我会写OO版本......
关于在某个目录中执行脚本/应用程序......仅仅是编写一个带参数的函数,并调用std.process.execute()
。如何扩展上面代码的一个非常快速的例子:
// WARNING: no error checking, etc!
int factoriel(int arg, int ignored) {
auto p = std.process.execute(["./funcs/factoriel", to!string(arg)]);
return to!int(p.output);
} // factoriel() function
...
// in main()
commands["fact"] = toDelegate(&factoriel);
...
execute("fact 6 0"); // again, we add 0 because we do not know how to do unary operations, yet. :)