闭包Closure

来源:互联网 发布:微博数据采集 编辑:程序博客网 时间:2024/05/21 17:45

闭包对于从函数式编程启蒙的童靴估计会很好理解,但是对于从JAVA这类纯粹OO启蒙的童靴,估计会比较困难。对于支持闭包的多数语言来说,函数都是作为第一级的对象,这就意味着:闭包可以被当做参数传递给函数,可以存储到变量中,也可以作为返回值。

那么什么是闭包?

闭包的定义是这样的:可以包含自由(未绑定)变量的代码块,这些变量不是在这个代码块或者任何全局上下文中定义的,而是在定义代码块的环境中定义。闭包一词来源于以下两者的结合:要执行的代码块(由于自由变量的存在,相关变量引用没有释放)和为自由变量提供绑定的计算环境(作用域)。

是不是很晦涩?

换句比较不那么折磨人的话说就是:闭包是一个可以引用外部作用域的变量,可以用作参数的代码块。

闭包形式上跟函数很像,但不是一般意义上的函数,闭包同时可以看做是一个对象。闭包中引用的外部变量,就是上面晦涩的闭包定义中所指的自由变量。

伟大的不知疲倦的布道者Martin Flower的解释

英文的:http: //martinfowler.com/bliki/Closures.html

中文的:http://blog.csdn.net/limux/archive/2005/07/05/413911.aspx

JAVA目前不支持闭包,我们看看几种动态语言中的闭包:

1、javascript中的闭包:

function a(){var i=0;function b(){alert(++i);}return b;}var c = a();c();

内部函数b()就是一个闭包。因为变量c对函数b()的引用,自由变量i在函数a()执行完之后不会被释放,从而可以保持自由变量的值。

其实javasript中的所有函数都可以理解成是闭包。

javascript闭包的延伸阅读

http://www.cn-cuckoo.com/2007/08/01/understand-javascript-closures-72.html

2、ruby中的闭包:

['lions', 'tigers', 'bears'].each {|item| puts item}


又如:

result = db.query “select * from words”;result.each {|row| do_something_with_row}


3、groovy中的闭包:

def one = { num1, num2 ->    println "param is: $num1 & $num2";}one(2, 3)       // 简便写法。输出 param is: 2 & 3one 2, 3        // 省略()的等效写法  one.call(2, 3) // 使用call方法one.call 2, 3  // 省略()等效写法

groovy闭包的延伸阅读

http://lggege.javaeye.com/blog/365242

4、python中的闭包:

def counter (st = 0)count = [st]def incr()count[0] = 1return count[0]return incrc = counter(5)


在JAVA中,可以通过内部类模拟闭包的行为:

JdbcTemplate template = new JdbcTemplate(dataSource);final List names = new LinkedList();template.query("SELECT id,name FROM types ORDER BY name",                           new RowCallbackHandler() {                               public void processRow(ResultSet rs)                                     throws SQLException                               {                                  names.add(rs.getString(1));                               }                            });


那么,如果JAVA引入闭包支持,我们就可以这么写:

JdbcTemplate template = new JdbcTemplate(dataSource);final List names = new LinkedList();template.query("SELECT id,name FROM types ORDER BY name",                               {                                  names.add(rs.getString(1));                               }                            );

是不是简洁很多?相信用Swing做桌面程序的童靴会有更大的感动。

闭包容易预见的好处是:

1、更简洁的代码;

2、更简练的模块:

3、更简明的抽象;

原创粉丝点击