2013-11-02 43 views
2

我遇到以下問題。Switch D在D中的替代

在輸入CONSOL中,我可以輸入一個字符串,系統會根據這個動作採取行動 。

所以,如果我輸入add_2_with_2,它會給我一個4,如果我輸入 sqrt_4它會給我2等。通常,你會做這樣一個 開關/ case命令,但問題是,那麼我需要每種情況下的 條件。所以如果我想ADITTIONALLY輸入 cube_2,那麼我必須爲此寫一個案例。

但是,我想這樣做,而不必明確地 每次插入一個新的命令時寫一個案例。因此,例如,如果在輸入「FUNCTION_1」中輸入 ,那麼程序應該在特定的 位置查找特定的forlder /文件,找出函數是否定義了 並執行它。如果沒有在文件/文件夾中定義, 那麼它應該拋出一個EXCEPTION。如果我另外想要 輸入「FUNCTION_2」,那麼我將在同一個 文件或文件夾中定義該函數(不管是否可以用D),然後讓原始程序自動搜索並執行。

這可以在D中完成嗎?

(對不起,愚蠢的問題和壞英文)

回答

3

是的,你可以,有幾種方法可以做到這一點。

1)您可以從一個程序中調用函數,並使用編譯時反射自動查找/映射它們。

我在我的終端仿真器的應用程序中做了這個。請參閱源代碼以瞭解我是如何做到的: https://github.com/adamdruppe/terminal-emulator/blob/master/utility.d

要將它用於您自己的目的,可以刪除version()語句,更改模塊名稱並編寫自己的函數。

2)您還可以在目錄中查找腳本並以這種方式運行它們。使用std.process和std.file來查找文件並運行它。

3

我相信你正在尋找的東西通常在文獻中稱爲Command Pattern。在大量的OO語言中,這種模式通常涉及創建一堆類,這些類實現了一個通用的簡單的接口,該接口具有單個​​方法。 然而,在D中,您有代表,並且可能避免爲此目的生成潛在的100個小類。

這裏是可能的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. :) 
+0

命令模式正好描述了我在尋找什麼 – Sean

+0

您至少可以爲答案投票或接受答案,因爲它會回答您的問題...... :) – DejanLekic

+0

投了......它描述了我的問題,但是我更喜歡其他答案,因爲它是解決方案的更多細節。 – Sean