2

我有以下问题。

在输入控制台中,我可以输入一个字符串,系统将根据该字符串执行操作。

因此,如果我输入 add_2_with_2,它会给我一个 4,如果我输入 sqrt_4 它会给我 2,依此类推。通常,您将使用 switch/case 命令执行此操作,但问题是,那么我需要为每个案子。因此,如果我想额外输入 cube_2,那么我必须为此编写一个案例。

但是,我想做同样的事情,而不必每次插入新命令时都显式地编写一个案例。例如,如果在输入“FUNCTION_1”中,那么程序应该在特定的地方,在特定的forlder /文件中查找函数是否已定义,然后执行它。如果文件/文件夹中没有定义,那么它应该抛出一个异常。如果我还想输入“FUNCTION_2”,那么我将在同一个文件或文件夹中定义函数(D 可以),然后让原始程序自动搜索和执行。

这可以在D中完成吗?

(对不起愚蠢的问题和糟糕的英语)

4

3 回答 3

3

碰巧,我只是做了这样的事情:

https://github.com/schancel/gameserver/blob/master/source/client/messaging.d

代码不是最漂亮的,但它使用反射来插入额外的 case 语句。

于 2013-11-02T19:08:29.673 回答
3

是的,你可以,有几种方法可以做到。

1)您可以从一个程序内部调用函数,并使用编译时反射自动查找/映射它们。

我在终端模拟器的实用程序中做到了这一点。查看源代码以了解我是如何做到的: https ://github.com/adamdruppe/terminal-emulator/blob/master/utility.d

要将其用于您自己的目的,您可以删除 version() 语句、更改模块名称并编写自己的函数。

2)您还可以在目录中查找脚本并以这种方式运行它们。使用 std.process 和 std.file 查找文件并运行它。

于 2013-11-02T19:09:06.817 回答
3

我相信您正在寻找的东西在文献中通常称为Command Pattern。在重度 OO 语言中,这种模式通常涉及创建一堆类,这些类实现了一个通用的、简单的Command接口,该接口只有一个execute()方法。然而,在 D 中,您有委托,并且可能可以避免为此目的生成潜在的数百个小类。

这是使用 lambda 表达式 ( http://dlang.org/expression.html#Lambda ) 的可能的 D 替代方案之一:

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

这是 fork 和玩的源代码: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. :)
于 2013-11-03T14:01:48.937 回答