今天我们来学习一下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脚本创建,读取循环的。