Я не эксперт в python, но вы могли бы попробовать: say
i = (1,2)
res = lambda i: (i[1],i[0])
print 'res(1, 2) = {0}'.format(res(1, 2))
выше дал бы o / p as:
res(1, 2) = (2,1)
Идиома Java для функциональности, подобной указателю на функцию, - это анонимный класс, реализующий интерфейс, например
Collections.sort(list, new Comparator<MyClass>(){
public int compare(MyClass a, MyClass b)
{
// compare objects
}
});
Обновление: вышеуказанное необходимо в версиях Java до Java 8. Теперь у нас есть гораздо более приятные альтернативы, а именно лямбды:
list.sort((a, b) -> a.isGreaterThan(b));
и ссылки на методы:
list.sort(MyClass::isGreaterThan);
Вы можете заменить указатель функции на интерфейс. Допустим, вы хотите просмотреть коллекцию и что-то сделать с каждым элементом.
public interface IFunction {
public void execute(Object o);
}
Это интерфейс, который мы могли бы передать некоторым, скажем, CollectionUtils2.doFunc (Collection c, IFunction f).
public static void doFunc(Collection c, IFunction f) {
for (Object o : c) {
f.execute(o);
}
}
В качестве примера скажем, что у нас есть набор чисел, и вы хотите добавить 1 к каждому элементу.
CollectionUtils2.doFunc(List numbers, new IFunction() {
public void execute(Object o) {
Integer anInt = (Integer) o;
anInt++;
}
});
Для достижения аналогичной функциональности вы можете использовать анонимные внутренние классы.
Если вы должны определить интерфейс Foo
:
interface Foo {
Object myFunc(Object arg);
}
Создайте метод bar
, который получит в качестве аргумента «указатель на функцию»:
public void bar(Foo foo) {
// .....
Object object = foo.myFunc(argValue);
// .....
}
Наконец, вызовите метод следующим образом:
bar(new Foo() {
public Object myFunc(Object arg) {
// Function code.
}
}
Нет, в java функции не являются объектами первого класса. Вы можете сделать то же самое, реализуя класс обработчика - вот как обратные вызовы реализованы в Swing и т. Д.
Однако есть предложения по закрытию (официальное название того, о чем вы говорите) в будущих версиях java - В Javaworld есть интересная статья.
В Java такого нет. Вам нужно будет обернуть вашу функцию в какой-либо объект и передать ссылку на этот объект, чтобы передать ссылку на метод этого объекта.
Синтаксически это можно в определенной степени облегчить, используя анонимные классы, определенные в place или анонимные классы, определенные как переменные-члены класса.
Пример:
class MyComponent extends JPanel {
private JButton button;
public MyComponent() {
button = new JButton("click me");
button.addActionListener(buttonAction);
add(button);
}
private ActionListener buttonAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
// handle the event...
// note how the handler instance can access
// members of the surrounding class
button.setText("you clicked me");
}
}
}
Здесь вспоминается Казнь Стива Йегге в Царстве существительных . По сути, в нем говорится, что Java нужен объект для каждого действия, и поэтому в нем нет сущностей «только для глаголов», таких как указатели на функции.
Проверьте замыкания, как они реализованы в библиотеке lambdaj. На самом деле они ведут себя очень похоже на делегатов C #:
Я внедрил поддержку обратного вызова / делегата в Java с использованием отражения. Детали и рабочий источник доступны на моем сайте .
Как это работает
У нас есть принципиальный класс с именем Callback с вложенным классом с именем Carms. API, который нуждается в обратном вызове, возьмут объект обратного вызова в качестве параметра, и, если необходимо, создайте обратный вызов. WithParms как переменная метода. Поскольку многие из приложений этого объекта будут рекурсивные, это работает очень чисто.
С исполнением до сих пор является высоким приоритетом для меня, я не хотел, чтобы создать массив накладных объектов для удержания параметров для каждого вызова - в конце концов в рамках большой структуры данных могут быть тысячи элементов, а в Сценарий обработки сообщений мы могли бы оказаться обработки тысяч структур данных в секунду.
Для использования Threadsafe массив параметров должен быть однозначно существует для каждого вызова метода API, а для эффективности того же следует использовать для каждого вызова обратного вызова; Мне нужен был второй объект, который будет дешевым для создания, чтобы связать обратный вызов с массивом параметров для вызова. Но в некоторых сценариях INSOOKE уже будет иметь массив параметра по другим причинам. По этим двум причинам массив параметров не принадлежал в объекте обратного вызова. Также выбор вызова (передача параметров как массив или в качестве отдельных объектов) принадлежит в руках API, используя обратный вызов, позволяющий использовать то, что вызов которого лучше всего подходит для его внутренней работы.
Вложенные классы с Apparms, затем являются необязательными и служат двумя целями, он содержит массив объекта параметра, необходимый для вызовов обратного вызова, и он предоставляет 10 методов перегрузки (с от 1 до 10), которые загружают параметр массив, а затем вызвать цель обратного вызова.
Для этого вы можете использовать отражение.
Передайте в качестве параметра объект и имя метода (в виде строки), а затем вызовите метод. Например:
Object methodCaller(Object theObject, String methodName) {
return theObject.getClass().getMethod(methodName).invoke(theObject);
// Catch the exceptions
}
А затем используйте его, как в:
String theDescription = methodCaller(object1, "toString");
Class theClass = methodCaller(object2, "getClass");
Конечно, проверьте все исключения и добавьте необходимые преобразования.