【 以下文字转载自 JobHunting 讨论区 】
发信人: yinyueyouge (隐约有歌), 信区: JobHunting
标 题: Re: java enclosure是什么-今天被hm问倒了
发信站: BBS 未名空间站 (Fri Oct 22 09:27:57 2010, 美东)
感觉对方是在问 Closure。
这个是 Java 对 Lambda 表达式的实现。Java 7 已经确定在语法上支持这个。
Java 6或者以前的版本只能靠 interface + anonymous class 来实现。
若是做过 functional programming(比如haskell),应该对 Lamdba 表达
式比较熟悉。
从C++的角度来看,就是 function pointer,但是它是 Strongly Typed。
举例代码来说明。假设要对二叉树遍历,代码很好写,比如:
void inOrder(Tree tree) {
if (tree != null) {
inOrder(tree.getLeft());
System.out.println(tree.getValue());
inOrder(tree.getRight());
}
}
但是如上的函数只是把Node的值打印到终端。若是要变得generic一点,要遍历的
过程中,能引入一个函数,对每一个Node执行这个函数,该多好。这样就引入了一
个概念:能否把函数当做一个对象,传递入inOrder函数呢?
可以用如下的代码调用inOrder函数(Java 7的语法比较雷):
inOrder(tree,
#(Tree tree)(System.out.println(tree.getValue())
);
inOrder的定义要修改成:
void inOrder(Tree tree, #()(Tree tree));
一些示范代码:
之一:
#int(int x) fc; // 声明一个 variable
fc = #(int x)(x + 1); // 第一个括号是引入参数,第二个括号是代码
int x = fc(4); // 4加1,得5,然后赋值给x
之二:
int y = #(int x)(x + 1).(3); // y = 3 + 1
住:如上的语法还不是final版本。。在Java 7出来之前一切都会有变动。
所以Closure其实包含2个部分:1是把每个函数当作对象,2是一个简化的匿名函数
的语法。
在Java 6的话,就用interface+匿名类来实现了:
interface Closure { public void invoke(T t); }
void inOrder(Tree tree, Closure closure) {
if (tree != null) {
inOrder(tree.getLeft());
closure.invoke(tree);
inOrder(tree.getRight());
}
}
执行的代码如此:
inOrder(tree, new Closure() {
public void invoke(Tree tree) {
System.out.println(tree.getValue());
}
});
Java的最初的设计,即所有函数必须属于一个对象,导致了对拉姆达表达式的支持
非常困难。写出来的代码让人非常雷。
相比之下,C#的语言就简介多了:
delegate void TraversalAction(Tree tree); // 一个函数模板
void InOrder(Tree tree, TraversalAction action) {
if (tree != null) {
InOrder(tree.getLeft());
action(tree); // 执行该函数
InOrder(tree.getRight());
}
}
执行的代码如此:
InOrder(tree,
{ tree => Console.WriteLine(tree) } // 一个代码片段
);
也可以这么执行:
// 把一个代码片段存放入variable中
var func = (TraversalAction) delegate (Tree tree) {
tree => Console.WriteLine(tree);
};
// 把func传入函数InOrder作为一个参数
InOrder(tree, func);
总结一点:拉姆达表达式就是把一个代码片段或者一个函数当作对象。该对象
可以赋值给variable,也可以作为函数的引入参数。
若是C/C++语言,最经典的例子就是qsort函数:
void qsort (
void * base,
size_t num,
size_t size,
int (*comparator)(const void*, const void*)
);
第四个参数,就是一个function pointer。在调用qsort函数的时候,可以
把另外一个函数当作参数直接调入qsort。