这里有一个具体的例子:http://rc.qzone.qq.com/100641772
今天我们来学习一下Lua中的迭代器:Iterator。
迭代器是一种可以遍历集合中所有元素的机制。在Lua中,通常将迭代器表示为函数,每调用一次函数,即返回集合中的下一个元素。
每个迭代器都需要在每次调用中保持一些状态,这样才可以知道它所在的位置以及如何进入到下一步。Closure为这类任务提供了很好的支持,一个Closure就是一种可以访问其外部嵌套环境中的局部变量函数。对于Closure而言,这些变量可以保持一种中间状态。
我们来写一个简单的迭代器:
function values(t) local i = 0 return function() i = i + 1; return t[i] end end
接下来,创建一些数据:
local days ={ "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday" }
写点东西去测试一下,这里我提到一点,写程序要像切香肠一样,一点一点地去写,写一点就去测试一下。或者有个想法,有个函数,都要这样去做。千万不要写了一大段之后,再去运行你的程序,那样一旦有错误,就要付出比开始测试高的多的代价去追踪。长此以往,对自己的程序逐级失去信心。因为这点,我非常喜欢,F#,Lua,Python这样的东东,可以让我随时地看到自己的想法,得到一个反馈。
do for item in values(days) do print(item) end end
我们得到了正确的结果,这样为下一步行动打下了基础。目前为止,我们所做的都是在Lua中做的,接下来要和Flash进行对接。
在前面三节中我们谈了不少Flash中调用Lua脚本的东西,这里不再多说了。
上代码:
package { import flash.display.Sprite; import fl.controls.Button; import fl.controls.Label; import flash.utils.ByteArray; import luaAlchemy.LuaAlchemy; import org.Middle; public class Iterator extends Sprite { [Embed(source="../luascript/iterator.lua",mimeType="application/octet-stream")] private static var luaClass:Class; public function Iterator() { var t:Middle = new Middle(); InitPage(); } private function InitPage():void { var luaArray:ByteArray = new luaClass() as ByteArray; var luaSt:String = luaArray.readUTFBytes(luaArray.bytesAvailable); var luaAlchemyObj:LuaAlchemy = new LuaAlchemy(); luaAlchemyObj.setGlobal("this", this); luaAlchemyObj.doString(luaSt); Middle.SetCanvas(this); luaAlchemyObj.doString("DoCircle()"); } } }
创建一个执行日历页面布局的类,里面建立一个静态方法,以日期字符串为参数。
package org { import fl.controls.Label; import flash.display.Sprite; public class Middle { private static var canvas:Sprite; private static var space:int = 0; public function Middle() { } public static function MakCalendar(_day:String):void { var label:Label = new Label(); label.text = _day; canvas.addChild(label); space += 100; label.x = space; label.y = 20; } public static function SetCanvas(_canvas:Sprite):void { canvas = _canvas; } } }
最后一步,返回到在Flash里面调用的脚本,大同小异,只是把输出语句,修改为调用日历构造语句
as3.trace("OK,Lua is ready.") local md = as3.class.org.Middle local days ={ "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday" } function values(t) local i = 0 return function() i = i + 1; return t[i] end end function DoCircle() for item in values(days) do md.MakCalendar(item) end end
我们最终得到了一个在Flash里面的日历。而这个日历的数据部分是用Lua脚本创建,读取循环的。