Java, эквивалентный из функции, отображающейся в Python

Чтобы ответить на конкретный вопрос об использовании #include с файлом .c (другие ответы предлагают лучшие варианты, особенно тот, который предлагает Groo), в общем, в этом нет необходимости.

Все в файле .c можно сделать внешне видимым и доступным, так что вы можете ссылаться на него через прототипы функций и #extern. Так, например, вы можете сослаться на свою таблицу с помощью #extern const MyElements elems []; в вашем основном файле .c.

Кроме того, вы можете поместить определения в файл .h и включить его. Это позволяет вам разделять код так, как вы хотите. Имейте в виду, что все, что делает #include, - это вставляет содержимое включаемого файла, где находится оператор #include, поэтому у него не должно быть какого-либо конкретного расширения файла. .h используется по соглашению, и большинство IDE автоматически добавляют файлы .c в список файлов для компиляции, но что касается компилятора, именование является произвольным.

9
задан Martijn Pieters 1 September 2016 в 15:02
поделиться

7 ответов

Есть несколько способов решения этой проблемы. Большинство из них уже были опубликованы:

  • Команды - Храните группу объектов, у которых есть метод execute () или invoke () на карте; найдите команду по имени, затем вызовите метод.
  • Полиморфизм - В более общем смысле, чем команды, вы можете вызывать методы для любого связанного набора объектов.
  • Наконец, есть Reflection - вы можете использовать отражение для получения ссылок в объекты java.lang.Method. Для набора известных классов / методов это работает довольно хорошо, и после загрузки объектов Method не возникает слишком больших накладных расходов. Вы можете использовать это, например, чтобы позволить пользователю вводить Java-код в командную строку, которую вы выполняете в режиме реального времени.

Лично я бы использовал командный подход. Команды хорошо сочетаются с шаблонными методами , позволяя вам применять определенные шаблоны для всех ваших командных объектов. Пример:

public abstract class Command {
  public final Object execute(Map<String, Object> args) {
    // do permission checking here or transaction management
    Object retval = doExecute(args);
    // do logging, cleanup, caching, etc here
    return retval;
  }
  // subclasses override this to do the real work
  protected abstract Object doExecute(Map<String, Object> args);
}

Я бы прибегал к отражению только тогда, когда вам нужно использовать этот вид сопоставления для классов, дизайн которых вы не контролируете, и для которых нецелесообразно создавать команды. Например, вы не могли открыть Java API в командной оболочке, создавая команды для каждого метода.

4
ответ дан 4 December 2019 в 09:14
поделиться

Как все говорили, Java не поддерживает функции как объекты первого уровня. Для этого вы используете Functor, который представляет собой класс, который обертывает функцию. У Стива Йегге отличная тирада по этому поводу.

Чтобы помочь вам с этим ограничением, люди пишут библиотеки функторов: jga , Commons Functor

0
ответ дан 4 December 2019 в 09:14
поделиться

К сожалению, Java не имеет функций первого класса, но учитывает следующий интерфейс:

public interface F<A, B> {
  public B f(A a);
}

Это моделирует тип для функций от типа A до типа B , как первоклассные ценности, которые вы можете передавать. Вам нужна Map > .

Функциональная Java - это довольно полная библиотека, сосредоточенная на функциях первого класса.

1
ответ дан 4 December 2019 в 09:14
поделиться

В Java нет первоклассных методов, поэтому шаблон команды - ваш друг ...

дискламер: код не протестирован!

public interface Command 
{
    void invoke();
}

Map<String, Command> commands = new HashMap<String, Command>();
commands.put("function1", new Command() 
{
    public void invoke() { System.out.println("hello world"); }
});

commands.get("function1").invoke();
15
ответ дан 4 December 2019 в 09:14
поделиться

Вы можете использовать Map или Map и т.д., а затем использовать map.get ("function1"). Invoke (...). Но обычно проблемы такого рода решаются более чисто, используя полиморфизм вместо поиска.

2
ответ дан 4 December 2019 в 09:14
поделиться

Пример полиморфизма ..

public interface Animal {public void speak();};
public class Dog implements Animal {public void speak(){System.out.println("treat? treat? treat?");}}
public class Cat implements Animal {public void speak(){System.out.println("leave me alone");}}
public class Hamster implements Animal {public void speak(){System.out.println("I run, run, run, but never get anywhere");}}

Map<String,Animal> animals = new HashMap<String,Animal>();
animals.put("dog",new Dog());
animals.put("cat",new Cat());
animals.put("hamster",new Hamster());
for(Animal animal : animals){animal.speak();}
1
ответ дан 4 December 2019 в 09:14
поделиться

Как упоминалось в других вопросах, Map с анонимными внутренними классами - это один подробный способ сделать это.

Вариантом является использование перечислений вместо анонимных внутренних классов. Каждая константа перечисления может реализовать / переопределить методы перечисления или реализованного интерфейса, почти так же, как метод анонимного внутреннего класса, но с немного меньшим беспорядком. Я считаю, что в Effective Java 2nd Ed рассматривается, как инициализировать карту перечислений. Для отображения имени перечисления просто требуется вызвать MyEnumType.valueOf (name) .

0
ответ дан 4 December 2019 в 09:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: