2

次の問題があります。

入力コンソールで文字列を入力すると、システムはそれに基づいてアクションを実行します。

したがって、add_2_with_2 を入力すると 4 が返され、sqrt_4 を入力すると 2 が返されます。通常、これは switch / case コマンドで行いますが、問題は、それぞれに条件が必要なことです。場合。したがって、cube_2 を ADITTIONALLY で入力したい場合は、このケースを作成する必要があります。

ただし、新しいコマンドを挿入するたびにケースを明示的に記述することなく、同じことをしたいと考えています。たとえば、入力が「FUNCTION_1」の場合、プログラムは特定のフォルダー/ファイル内の特定の場所を調べ、関数が定義されているかどうかを調べて実行する必要があります。ファイル/フォルダーで定義されていない場合は、例外をスローする必要があります。さらに「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) 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と呼ばれています。オブジェクト指向の多い言語では、通常、このパターンには、単一のメソッドを持つ共通のシンプルなCommandインターフェイスを実装する一連のクラスの作成が含まれます。execute()ただし、D ではデリゲートがあり、おそらくこの目的のために数百もの小さなクラスを生成することを避けることができます。

ラムダ式 ( http://dlang.org/expression.html#Lambda )を使用した D の代替案の 1 つを次に示します。

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. :)
于 2013-11-03T14:01:48.937 に答える