作者:加QQ873759613 | 来源:互联网 | 2023-06-12 16:32
函数对象就是这样。既是对象又是功能的东西。
另外:将函数对象称为“函子”是对术语的严重滥用:另一种“函子”是数学的中心概念,并且在计算机科学中具有直接作用(请参阅“
Haskell函子”)。该术语在ML中的使用也略有不同,因此,除非您正在Java中实现这些概念之一(可以!),否则请停止使用此术语。它使简单的事情变得复杂。
返回答案:Java没有“一流的函数”,也就是说,您不能将函数作为参数传递给函数。从语法上讲,这在字节代码表示的多个级别上都适用,并且类型系统缺少“函数构造函数”
换句话说,您不能这样写:
public static void tentimes(Function f){
for(int i = 0; i <10; i++)
f();
}
...
public static void main{
...
tentimes(System.out.println("hello"));
...
}
这确实很烦人,因为我们希望能够做一些事情,例如拥有图形用户界面库,您可以在其中将“回调”功能与单击按钮相关联。
那么我们该怎么办?
好吧,一般的解决方案(由其他发布者讨论)是用一个我们可以调用的方法定义一个接口。例如,Java一直在使用Runnable
用于此类事情的接口,它看起来像:
public interface Runnable{
public void run();
}
现在,我们可以从上面重写我的示例:
public static void tentimes(Runnable r){
for(int i = 0; i <10; i++)
r.run();
}
...
public class PrintHello implements Runnable{
public void run{
System.out.println("hello")
}
}
---
public static void main{
...
tentimes(new PrintHello());
...
}
显然,这个例子是人为的。我们可以使用匿名内部类使此代码更好一些,但这可以理解。
Here is where this breaks down: Runnable
is only usable for functions that
don’t take any arguments, and don’t return anything useful, so you end up
defining a new interface for each job. For example, the interface Comparator
in Mohammad Faisal’s answer. Providing a more general approach, and one that
takes syntax, is a major goal for Java 8 (The next version of Java), and was
heavily pushed to be included in Java 7. This is called a “lambda” after the
function abstraction mechanism in the Lambda Calculus. Lambda Calculus is both
(perhaps) the oldest programming language, and the theoretical basis of much
of Computer Science. When Alonzo Church (one of the main founders of computer
science) invented it, he used the Greek letter lambda for functions, hence the
name.
其他语言,包括功能语言(Lisp,ML,Haskell,Erlang等),大多数主要动态语言(Python,Ruby,Javascript等)和其他应用程序语言(C#,Scala,Go,D等)支持某种形式的“
Lambda文字”。甚至C 现在都拥有它们(自C 11起),尽管在这种情况下它们会更加复杂,因为C
++缺乏自动内存管理功能,并且不会为您保存堆栈框架。