Переключатель cas Альтернатива в D

У меня следующая проблема.

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

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

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

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

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

3 ответа

Решение

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

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

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

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

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

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

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

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

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

Вот одна из возможных альтернатив D, использующих лямбда-выражения ( http://dlang.org/expression.html):

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

Я напишу ОО версию, когда найду больше времени...

Что касается выполнения скрипта / приложения в некотором каталоге... Это просто вопрос написания функции, которая принимает параметры и вызывает 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. :)
Другие вопросы по тегам