Lua语言入门(三)

协同程序

36、协同程序(coroutine)
4种状态:挂起(suspended)、运行(running)、死亡(dead)、正常(normal)

创建(挂起状态):

local co = coroutine.create(
 function()
  print("coroutine")
 end)

启动或再次启动协程(状态由挂起改为运行):

coroutine.resume(co)

coroutine在创建的时候不会自动执行。

检查协程的状态:

coroutine.status(co)

协程在运行完之后,就处于死亡状态,再也无法返回。

使用yield:

local co =  coroutine.create(
 function()
  for i=1,10 do
   print(i)
   coroutine.yield() --运行到这里让该协程挂起,之后通过调用coroutine.resume恢复它的运行
  end
 end
 )

coroutine.resume(co) --1
coroutine.resume(co) --2
coroutine.resume(co) --3
coroutine.resume(co) --4
coroutine.resume(co) --5

当一个协程 A 唤醒另一个协程 B ,协程 A 就处于一个特殊状态,称为“正常状态”。

local co =  coroutine.create(
 function(a, b)
  print("the first resume params: ", a, b);  --在第一次调用resume,传递的额外参数都将视为协同程序主函数的参数;
  print("resume params", coroutine.yield("yield return params")) --而yield返回值就是对应resume传入的参数

  return "function return"  --当一个协同程序结束时,主函数返回值都将作为resume的返回值。
 end
 )

print(coroutine.resume(co, 1, 2))  --调用resume后返回的内容,第一个值为true则表示没有错误,后面所有值都是对应yield传入的值
print(coroutine.resume(co, 3, 4, 5))

--[[
输出:
the first resume params: 1 2
true yield return params

resume params 3 4 5
true function return
]]

36、协程应用于生产者消费者模式(最好把代码运行一下,再去理解)

function receive(prod)
 local status, value = coroutine.resume(prod)
 return value
end

function send(x)
 coroutine.yield(x)
end

function producer()
 return coroutine.create(
  function()
   while true do
    local x = io.read()
    send(x)
   end
  end
 )
end

function filter(prod)
 return coroutine.create(
  function()
   for line = 1, math.huge do
    local x = receive(prod)
    x = string.format("%5d %s", line, x)
    send(x)
   end
  end
 )
end

function consumer(prod)
 while true do
  local x = receive(prod)
  io.write(x, "\n")
 end
end

p = producer()
f = filter(p)
consumer(f)

37、非抢先式多线程(协程):当一个协程运行时,无法从外部停止,只有协程显示的挂起(yield),才会停止。

常用数据结构

38、数组:以数字作为key的table,在lua中习惯用 1 作为数组起始,长度可变

a = {}
for i =1,10 do
 a[i] = 0
end
print(#a) --计算数组长度

--直接创建并初始化数组
a = {7, 6, 5, 5, 7, 8, 9, 0, 0, 5, 3}

39、多维数组,可以用类似其它语言的方式表示多维,也可以利用一维数组表示。用稀疏矩阵表示一个图,table本身就是稀疏的,可以直接表示浪费内存。

mt = {}
for i=1,10 do
 mt[i] = {}
 for j=1,10 do
  mt[i][j] = 0
 end
end

遍历“稀疏矩阵”需要注意:一般使用pairs且只遍历那些非nil的元素。

pairs 和 ipairs 的区别:pairs 可以遍历表中所有的key,而ipairs 只能遍历到表中出现的一个不是整数的key

当然还有链表、队列、树、图等数据结构,这就不详细写了,这些东西和在其它语言里面是一样的

40、字符串连接:先把每个字符串存到一个数组里面,然后用table.concat连接,比用(..)连接更快更省

local a = {"A", "b", "C", "d", "E"} 
local s = table.concat(a)

数据持久化

41、数据文件(读取):lua常常被用来做数据存取,在lua中,所谓的数据文件就是按一定格式定义的lua文件,把该“数据文件”加载进内存,就可以直接用lua代码解析了。

local  count = 0
function Entry(b)
 count = count + 1
 print("load data call : "..b[1])
end

--dofile("data")
--data文件中就写如下的代码,这里为了简便,就直接把数据写在这里了。
Entry{--注意数据文件里面的Entry必须提前定义,其实数据文件里面的Entry在调用一个名叫Entry的函数
 "A", "B", "C", "D", "E"
}
Entry{
 "f", "g", "h", "i", "j"
}
print("number of entries : "..count)

42、数据持久化
保存无“环”形table:

function serialize(o)
 if type(o) == "number" then
  io.write(0)
 elseif type(o) == "string" then
  io.write(string.format("%q", o))
 elseif type(o) == "table" then
  io.write("{\n")
  for k,v in pairs(o) do
   io.write("  [")
   serialize(k);
   io.write("] = ")
   serialize(v)
   io.write(", \n")
  end
  io.write("}\n")
 else
  --其它情况
  error("can not serialize a"..type(o))
 end
end

serialize({a = 'A', b = 'Q', c = '1'})

保存有“环”形table:

43、元表:就是普通一个table,可以设置为其他表的元表,元表中可定义实现一系列的元方法

t = {}
t1 = {x = "a"}
setmetatable(t, t1) --把 t1 设置为 t 的元表
print(getmetatable(t)) --获得 t 的元表

44、元方法:定义于元表中的那些重载的方法

算术类元方法(__add(加法),__mul(乘法),__sub(减法),__div(除法),__unm(相反数),__mod(取模),__pow(幂)):

local t = {}
t.__add = function(a, b) --定义加法的元方法
 return a["value"] + b["value"]
end

local obj1 = {value = 1}
setmetatable(obj1, t) --
local obj2 = {value = 2}
--setmetatable(obj1, t)

print(obj1 + obj2) --加法的时候,会检查它们其中任意一个的元表,只要有名叫__add的元方法,就会调用它定义的加法运算

关系类元方法(__eq(等于)、__lt(小于)、__le(等于)):

字符串输出元方法(__tostring):
local m = {}
m.__tostring = function()
 return "meta function"
end

local a = {}
setmetatable(a, m)

print(a)

保护元表:使用用户既不能看也不能修改集合的元表,定义字段 __metatable

local m = {}
m.__metatable = "not your business" --保护元表

local a = {}
setmetatable(a, m)

print(getmetatable(a)) --not your business
setmetatable(a, m) --cannot change protected metatable

table访问的元方法:
__index元方法:当访问一个table中不存在的字段时,解释器会去查找元表中名叫__index的元方法,如果没有该方法,返回nil,否则由这个元方法提供结果。

local m = {}
m.__index = function()
 return "index nil"
end

local a = {}
setmetatable(a, m)

print(a[1]) --index nil

__newindex元方法:当对一个table中不存在的索引赋值时,解释器就会查找__newindex元方法,如果元表中有该元方法,就调用它而不执行赋值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
lua中文教程,原名:programming in lua 目录 版权声明..............i 译序..i 目录iii 第一篇语言.......1 第0章序言.......1 0.1 序言..........1 0.2 Lua的使用者................2 0.3 Lua的相关资源............3 0.4 本书的体例.................3 0.5 关于本书...3 0.6 感谢..........4 第1章起点.......5 1.1 Chunks.......5 1.2 全局变量...7 1.3 词法约定...7 1.4 命令行方式.................7 第2章类型和值9 2.1 Nil..............9 2.2 Booleans....9 2.3 Numbers...10 2.4 Strings......10 2.5 Functions.12 2.6 Userdata and Threads.12 第3章表达式..13 3.1 算术运算符...............13 3.2 关系运算符...............13 3.3 逻辑运算符...............13 3.4 连接运算符...............14 3.5 优先级.....15 3.6表的构造..15 第4章基本语法................18 4.1 赋值语句.18 4.2 局部变量与代码块(block)......19 4.3 控制结构语句...........20 Programming in Lua iv Copyright ® 2005, Translation Team, www.luachina.net 4.4 break和return语句......23 第5章函数......24 5.1 返回多个结果值.......25 5.2可变参数..27 5.3 命名参数.28 第6章再论函数................30 6.1 闭包........32 6.2 非全局函数...............34 6.3 正确的尾调用(Proper Tail Calls)...36 第7章迭代器与泛型for....40 7.1 迭代器与闭包...........40 7.2 范性for的语义...........42 7.3 无状态的迭代器.......43 7.4 多状态的迭代器.......44 7.5 真正的迭代器...........45 第8章编译·运行·调试47 8.1 require函数.................49 8.2 C Packages.................50 8.3 错误........51 8.4 异常和错误处理.......52 8.5 错误信息和回跟踪(Tracebacks)....53 第9章协同程序................56 9.1 协同的基础...............56 9.2 管道和过滤器...........58 9.3 用作迭代器的协同...61 9.4 非抢占式多线程.......63 第10章完整示例..............68 10.1 Lua作为数据描述语言使用........68 10.2 马尔可夫链算法.....71 第二篇 tables与objects........75 第11章数据结构..............76 11.1 数组......76 11.2 阵和多维数组.........77 11.3 链表......78 11.4 队列和双端队列.....78 11.5 集合和包.................80 11.6 字符串缓冲.............80 第12章数据文件与持久化..................84 12.1 序列化...86 Programming in Lua v Copyright ® 2005, Translation Team, www.luachina.net 第13章 Metatables and Metamethods...92 13.1 算术运算的Metamethods............92 13.2 关系运算的Metamethods............95 13.3 库定义的Metamethods................96 13.4 表相关的Metamethods................97 第14章环境..103 14.1 使用动态名字访问全局变量...103 14.2声明全局变量........104 14.3 非全局的环境.......106 第15章 Packages.............109 15.1 基本方法...............109 15.2 私有成员(Privacy)................111 15.3 包与文件................112 15.4 使用全局表............113 15.5 其他一些技巧(Other Facilities)...115 第16章面向对象程序设计.................118 16.1 类.........119 16.2 继承.....121 16.3 多重继承...............122 16.4 私有性(privacy)...................125 16.5 Single-Method的对象实现方法127 第17章 Weak表...............128 17.1 记忆函数...............130 17.2 关联对象属性.......131 17.3 重述带有默认值的表...............132 第篇标准库134 第18章数学库................135 第19章 Table库...............136 19.1数组大小................136 19.2 插入/删除..............137 19.3 排序.....137 第20章 String库..............140 20.1 模式匹配函数.......141 20.2 模式.....143 20.3 捕获(Captures).146 20.4 转换的技巧(Tricks of the Trade)151 第21章 IO库..157 21.1 简单I/O模式..........157 21.2 完全I/O 模式........160 Programming in Lua vi Copyright ® 2005, Translation Team, www.luachina.net 第22章操作系统库........165 22.1 Date和Time............165 22.2 其它的系统调用...167 第23章 Debug库..............169 23.1 自省(Introspective)..............169 23.2 Hooks...173 23.3 Profiles.174 第四篇 C API..177 第24章 C API纵览..........178 24.1 第一个示例程序...179 24.2 堆栈.....181 24.3 C API的错误处理..186 第25章扩展你的程序....188 25.1 表操作.189 25.2 调用Lua函数.........193 25.3 通用的函数调用...195 第26章调用C函数..........198 26.1 C 函数..198 26.2 C 函数库................200 第27章撰写C函数的技巧..................203 27.1 数组操作...............203 27.2 字符串处理...........204 27.3 在C函数中保存状态.................207 第28章 User-Defined Types in C........212 28.1 Userdata.................212 28.2 Metatables..............215 28.3 访问面向对象的数据...............217 28.4 访问数组...............219 28.5 Light Userdata........220 第29章资源管理............222 29.1 目录迭代器...........222 29.2 XML解析...............225
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值