2013-11-02 8 views
2

У меня есть следующая проблема.Switch cas Alternative in D

В входной консоли я могу ввести строку, и система будет принять меры на основе таких.

Так что, если я вход add_2_with_2, это даст мне 4, если вход sqrt_4 это даст мне 2 и т.д. В общем, вы будете делать это с помощью команды в переключатель/случай, но проблема в том, то Мне нужно условие для каждого случая. Поэтому, если я хочу ДОПОЛНИТЕЛЬНО ввести cube_2, тогда я должен написать для этого случай.

Тем не менее, я хотел бы сделать то же самое без необходимости явно указывать случай каждый раз, когда я вставляю новую команду. Так что, например, если на входе «FUNCTION_1», программа должна смотреть в определенном месте в определенном файле forlder/file, если определена функция и выполнить ее. Если он не определен в файле/папке, , тогда он должен выбросить ИСКЛЮЧЕНИЕ. Если я дополнительно хочу ввести вход «FUNCTION_2», тогда я определю функцию в том же файле или папке (что возможно с помощью D), а затем позволить оригинальной программе автоматически выполнять поиск и выполнение.

Можно ли это сделать в D?

(извините за глупый вопрос, и плохой английский)

ответ

3

Да, вы можете, есть несколько способов сделать это.

1) Вы можете вызывать функции из одной программы и автоматически находить/сопоставлять их, используя отражение времени компиляции.

Я сделал это в своей утилите для эмулятора терминала. Посмотрите источник, чтобы узнать, как я это сделал: https://github.com/adamdruppe/terminal-emulator/blob/master/utility.d

Чтобы использовать его в своих целях, вы можете удалить операторы version(), изменить имя модуля и написать свои собственные функции.

2) Вы также можете найти сценарий в каталоге и запустить его таким образом. Используйте std.process и std.file, чтобы найти файл и запустить его.

3

Как это происходит, я только что сделал что-то вроде этого:

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

Кодекс не является самым симпатичным, но он использует отражения для вставки заявления о дополнительных случаях.

+0

Приятный, вы также использовали функции std.traits вместо __traits, как я. –

3

Я полагаю, что вы ищете, как правило, называют в литературе как . В сильно OO-языках этот шаблон обычно включает создание группы классов, которые реализуют простой, простой интерфейс , который имеет один метод execute(). В D, однако, у вас есть делегаты, и, возможно, вы не сможете создать потенциально сотни небольших классов для этой цели.

Вот один из возможных D альтернатив, с помощью лямбда-выражения (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

Command Pattern точно описывает, что я искал – Sean

+0

Вы могли бы хотя бы проголосовать за ответ или принять его, так как он отвечает на ваш вопрос ... :) – DejanLekic

+0

проголосовал ...... он описывает мою проблему, но i предпочитают другой ответ, поскольку это более подробно решение – Sean

 Смежные вопросы

  • Нет связанных вопросов^_^