1. 举个简单的栗子:
1.1 JavaScript:
let func = (s)=> { console.log(s); }; func("hello world");
1.2 Java:
interface Operate { void doSomething(String str); // void doSomething1(); 不可以有两个方法 } public static void main(String[] args) { Operate func = (String s)->{ System.out.println(s);}; func.doSomething("hello world"); }
1.3 C#:
var func = (string s)=> { Console.WriteLine(s); }; func("hello world");
1.4 分析
可以看到,写法非常类似,尤其是Js和C#。 变量func可以被当做一个函数来使用。
那么用于承接这个匿名方法的变量实际是什么?
JavaScript: 就是一个js中的function
Java: 在例子中,有点容易迷惑,明明是将lambda赋值给了一个接口类型。但最终调用的时候又要调用该接口的doSomething方法。而且这个接口只能有一个对应的方法,多了会报错。
Java10中也提供了var关键字,但遗憾的是也不能被用于这样lambda赋值的情况。
C#: 实际上是一个委托类型,例如:
delegate void doSomething(string str); public static void Main(string[] args) { doSomething func = (string s) => { Console.WriteLine(s); }; func("hello world"); }
这样看和Java有点像了,但定义的仍然是一个方法,而不是一个接口中有一个同样类型的方法。
- 如果在c语言中我们会用一个指向函数的指针。
2. 对函数外变量的引用
在上一节的例子中,“hello world”是以参数的形式传递到方法中的,那么,是否可以直接引用外部的方法呢?
当然是可以的,改造一下上面的例子:
2.1 JavaScript:
let str = ",圣诞快乐。"; let func = (s)=> { console.log(s + str); str = ",春节快乐。" }; str = ",元旦快乐。" func("hello world"); func("hello world");
2.2 Java:
interface Operate { void doSomething(String str); // void doSomething1(); 不可以有两个方法 } public static void main(String[] args) { final String str = ",圣诞快乐"; Operate func = (String s)->{ System.out.println(s + str); //str = ",春节快乐。"; }; //str = ",元旦快乐。" func.doSomething("hello world"); }
2.3 C#:
var str = ",圣诞快乐。"; var func = (string s) => { Console.WriteLine(s + str ); str = ",春节快乐。"; }; str = ",元旦快乐。"; func("hello world"); func("hello world");
2.4 分析
- JavaScript 和C# 的结果是一样的,输出结果为:
hello world,元旦快乐。 hello world,春节快乐。
- 可见,在函数执行的时候,会取当时str的值。在函数定义的时候,虽然引用了变量str,但不是此时固定了str的值。
在函数中改变了str的值,会改变外部str的值。 - Java的例子中,要求str是final的才行,所以是无法对str改变的。