Lua

Lua学习笔记:迭代和闭包

Posted by 蔡华的博客 on August 14, 2017

关系

  • 迭代是一种遍历一种集合中所有元素的机制,在遍历的过程中需要在每次成功之间保持一些状态,比如当前变量的index等。而闭包的机制恰好很适合迭代,因为闭包是一种可以访问外部嵌套环境中的变量的函数,而这个变量可以用来保持状态。在lua中闭包结构通常由闭包函数本身和一个创建该闭包函数的工厂函数组成。
  • 以下面代码为例,GetValue就是个工厂,它生产出一个闭包,这个闭包将状态保持在t和i这两个变量中。其实在我看来主要是i中。在循环中每次调用闭包(迭代器)都是在更新它的状态i。这段代码完美的展示了迭代器的概念,看完之后对于迭代的理解更近了一步。
tt = {10,20,30}

function GetValue(t)
	local i =0
	return function ()
		i=i+1
		return t[i]
	end
end

iterator = GetValue(tt)

while true do
	local v = iterator()
	if v == nil then
		break
	end
	print(v)
end

泛型for

  • 泛型for在内部保存了3个值,分别是一个迭代器函数、一个恒定状态和一个控制变量。其形态如下,其中var-list是变量列表,exp-list表达式列表。var-list第一个原始就是控制变量,在循环中它不会是nil,如果是nil了循环就结束了。
for <var-list> in <exp-list> do
    <body>
end
  • 迭代器是for中内部保存的,恒定状态应该是你需要循环的数据,比如一个table,控制变量是返回值变量列表的第一个变量,同时它也是用恒定状态和控制变量调用迭代器后得到的结果。假设迭代器函数是f,恒定状态是s,控制变量初始是a0,那么有a1 = f(s,a0) a2 = f(s,a1)...

  • lua中将for的迭代器返回值固定为了3个,因此得到的是next\t\nil.

无状态迭代器

  • 不保存任何状态的迭代器,可以在多个循环中使用同一个迭代器。例子:ipairs。准确说ipairs是个工厂,它生产了一个简单的迭代器。

  • 一个简单的迭代器

local function getNext(list, node)
	if not node then
		return list
	else
		return node.next
	end
end

function tra(list)
	return getNext,list,nil
end

list = nil
for line in io.lines() do
	list  = {val = line, next = list}
end

for node in list do
	print(tra(node.val))
end

关于迭代的的一些理解

  • 在lua中for迭代的迭代器其实主要是个生成器,它生成了iterator,然后依靠for来循环调用。注意生成迭代的函数的返回值必须是函数、恒定状态、控制变量这个顺序。