Lua学习笔记(3)

协同程序

Lua将所有关于协同程序的函数放置在一个名为”coroutine”的table中。函数create用于创建新的协同程序,它只有一个参数,就是一个函数,函数代码就是所需执行的内容。create会返回一个thread类型的值,用以表示新的协同程序。通常create的参数是一个匿名函数:

1
2
co = coroutine.create(function () print("hi") end)
print(co) -->thread: 0x7fa97b404f60

一个协同程序可以处于4种不同的状态:

  • 挂起(suspended)
  • 运行(running)
  • 死亡(dead)
  • 正常(normal)

当创建一个协同程序时,它处于挂起状态。也就是说,协同程序不会在创建它时自动执行其内容。可以通过函数status来检查协同程序的状态:

1
print(coroutine.status(co)) --> suspended

函数coroutine.resume用于启动或再次启动一个协同程序的执行,并将其状态由挂起改为运行:

1
coroutine.resume(co) --> hi

协同程序的内容只是简单地打印了”hi”后便终结了,然后它就处于死亡状态,也就再也无法返回了:

1
print(coroutine.status(co)) --> dead

其实协同程序的真正强大之处在于函数yield的使用上,该函数可以让一个运行中的协同程序挂起,而之后可以再回复它的运行。
在第一次调用resume时,并没有对应的yield在等待它,因此所有传递给resume的额外参数都将视为协同程序主函数的参数:

1
2
3
4
co = coroutine.create(function (a, b, c)
print("co", a, b, c)
end)
coroutine.resume(co, 1, 2, 3) --> co 1 2 3 //1, 2, 3就是额外传入的参数

在resume调用返回的内容中,第一个值为true则表示没有错误,则后面所有的值都是对应yield传入的参数:

1
2
3
4
co = coroutine.create(function (a, b)
coroutine.yield(a + b, a - b)
end)
print(coroutine.resume(co, 20, 10)) --> true 30 10

与此对应的是,yield返回的额外值就是对应resume传入的参数:

1
2
3
4
5
co = coroutine.create(function ()
print("co", coroutine.yield())
end)
coroutine.resume(co)
coroutine.resume(co, 4, 5) --> co 4 5

最后,当一个协同程序结束时,它的主函数所返回的值都将作为对应的resume的返回值:

1
2
3
4
co = coroutine.create(function()
return 6, 7
end)
print(coroutine.resume(co)) --> true 6 7

##数据结构
矩阵多维数组,使用以下代码创建N*M的矩阵:

1
2
3
4
5
6
7
mt = {}
for i=1, N do
mt[i] = {}
for j=1, M do
mt[i][j] = 0
end
end

链表,使用以下代码创建一个链表:

list = nil //先创建头结点
list = {next = list, value = v}//在表头插入一个元素,元素值为v
local l = list
while l do
    <访问l.value>
    l = l.next
end //遍历此列表