快速业务通道

闭包的概念、形式与应用

作者 佚名技术 来源 Linux系统 浏览 发布时间 2012-05-07
元素呢?解决这些问题都要对数组进行遍历,如果是在不支持闭包的语言中,我们不得不一次又一次重复地写循环语句.而这在支持闭包的语言中是不必要的,比如对数组求和的操作在 Ruby 中可以这样做:
Empire CMS,phome.net


清单 10. 加强模块化

nums = [10,3,22,34,17]
sum = 0
nums.each{|n| sum = n}
print sum


这种处理方法多少有点像我们熟悉的回调函数,不过要比回调函数写法更简单,功能更强大.在闭包里引用环境是函数定义时的环境,在闭包里改变引用环境中变量的值,直接就可以反映到它定义时的上下文中,这是通常的回调函数所不能做到的.这个例子说明闭包可以使我们把模块划分得更小.

抽象

闭包是数据和行为的组合,这闭包具有较好抽象能力,下面的代码通过闭包来模拟面向对象编程.函数 make_stack 用来生成 stack 对象,它的返回值是一个闭包,这个闭包作为一个 Dispatcher,当以 “push” 或 “pop” 为参数调用时,返回一个与函数 push 或 pop 相关联的闭包,进而可以操作 data 中的数据.


清单 11. 抽象

function make_stack()

local data = {};
local last = -1;

local function push(e)
last = last 1;
data[last] = e;
end

local function pop()
if last == -1 then
return nil
end
last = last - 1
return data[last 1]
end

return function (index)
local tb = {push=push, pop=pop}
return tb[index]
end
end

s = make_stack()

s("push")("test0")
s("push")("test1")
s("push")("test2")
s("push")("test3")

print(s("pop")())
print(s("pop")())
print(s("pop")())


如果加入一些方便调用“对象方法”的语法糖,这看起来很像是面向对象的语法.当然 Lua 中有自己的面向对象语法和机制,几乎看不到有人写这样的 Lua 代码,但是对于 Scheme 等没有内建面向对象支持也没有内建复杂数据抽象机制的语言,使用闭包来进行抽象是非常重要的手段.

简化代码

我们来考虑一个常见的问题.在一个窗口上有一个按钮控件,当点击按钮时会产生事件,如果我们选择在按钮中处理这个事件,那就在按钮控件中保存处理这个事件时需要的各个对象的引用.另一种选择是把这个事件转发给父窗口,由父窗口来处理这个事件,或是使用监听者模式.无论哪种方式,编写代码都不太方便,甚至要借助一些工具来帮助生成事件处理的代码框架.用闭包来处理这个问题则比较方便,可以在生成按钮控件的同时就写下事件处理代码.比如在 Ruby 中可以这样写:

Empire CMS,phome.net


清单 12. 简化代码

song = Song.new
start_button = MyButton.new("Start") { song.play }
stop_button = MyButton.new("Stop") { song.stop }

更多

闭包的应用远不止这些,这里列举的只能算是冰山一角而已,并且更多的用法还不断发现中.要想了解更多的用法,多看一些代码应该是个不错的选择.

总结

闭包能优雅地解决很多问题,很多主流语言也顺应潮流,已经或将要引入闭包支持.相信闭包会成为更多人爱不释手的工具.闭包起源于函数语言,也许掌握一门函数语言是理解闭包的最佳途径,通过学习函数语言可以了解不同的编程思想,有益于写出更好的程序.

Empire CMS,phome.net

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号