基础
nil 相当于python的null boolean 布尔值 number 表示双精度类型的实浮点数 string 字符串由一对双引号或单引号来表示 使用#str返回字符串长度 function 由 C 或 Lua 编写的函数 thread 表示执行的独立线路,用于执行协同程序 table Lua 中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字或者是字符串。在 Lua 里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表。 使用泛型for循环遍历,如果遇到nil则停止遍历。
#while a=10 while( a < 20 ) do print("a 的值为:", a) a = a+1 end #for for var=exp1,exp2,exp3 do <执行体> end #var从exp1变化到exp2,每次变化以exp3为步长递增var,并执行一次"执行体"。exp3是可选的,如果不指定,默认为1。三个条件如果有计算,只在第一次运行计算一次。 #泛型for for i,v in ipairs(a) do print(v) end # repeat...until repeat statements until( condition ) #无条件执行第一次。
if(0) then print("0 为 true") end #Lua认为false和nil为假,true和非nil为真. 0为真
函数
optional_function_scope function function_name( argument1, argument2, argument3..., argumentn) function_body return result_params_comma_separated end optional_function_scope: 该参数是可选的制定函数是全局函数还是局部函数,未设置该参数默认为全局函数,如果你需要设置函数为局部函数需要使用关键字 local。 function_name: 指定函数名称。 argument1, argument2, argument3..., argumentn: 函数参数,多个参数以逗号隔开,函数也可以不带参数。 function_body: 函数体,函数中需要执行的代码语句块。 result_params_comma_separated: 函数返回值,Lua语言函数可以返回多个值,每个值以逗号隔开。
function average(...) result = 0 local arg={...} for i,v in ipairs(arg) do result = result + v end print("总共传入 " .. #arg .. " 个数") return result/#arg end print("平均值为",average(10,5,3,4,5,6)) #Lua函数可以接受可变数目的参数,和C语言类似在函数参数列表中使用三点(...) 表示函数有可变的参数。 Lua将函数的参数放在一个叫arg的表中,#arg 表示传入参数的个数。
字符串三种表达方式: 单引号,双引号,[[str]] 转义符是\ 匹配模式 式匹配函数 string.find, string.gmatch, string.gsub, string.match。 你还可以在模式串中使用字符类 除 ^$()%.[]*+-? 外字符都和自身相匹配 (点): 与任何字符配对 %a: 与任何字母配对 %c: 与任何控制符配对(例如\n) %d: 与任何数字配对 %l: 与任何小写字母配对 %p: 与任何标点(punctuation)配对 %s: 与空白字符配对 %u: 与任何大写字母配对 %w: 与任何字母/数字配对 %x: 与任何十六进制数配对 %z: 与任何代表0的字符配对 %x(此处x是非字母非数字字符): 与字符x配对. 主要用来处理表达式中有功能的字符(^$()%.[]*+-?)的配对问题, 例如%%与%配对 [数个字符类]: 与任何[]中包含的字符类配对. 例如[%w_]与任何字母/数字, 或下划线符号(_)配对 [^数个字符类]: 与任何不包含在[]中的字符类配对. 例如[^%s]与任何非空白字符配对 当上述的字符类用大写书写时, 表示与非此字符类的任何字符配对. 例如, %S表示与任何非空白字符配对.例如,'%A'非字母的字符,其中%作为转义符 单个字符类匹配该类别中任意单个字符; 单个字符类跟一个 '*', 将匹配零或多个该类的字符。 这个条目总是匹配尽可能长的串; 单个字符类跟一个 '+', 将匹配一或更多个该类的字符。 这个条目总是匹配尽可能长的串; 单个字符类跟一个 '-', 将匹配零或更多个该类的字符。 和 '*' 不同, 这个条目总是匹配尽可能短的串; 单个字符类跟一个 '?', 将匹配零或一个该类的字符。 只要有可能,它会匹配一个; %n, 这里的 n 可以从 1 到 9; 这个条目匹配一个等于 n 号捕获物(后面有描述)的子串。 %bxy, 这里的 x 和 y 是两个明确的字符; 这个条目匹配以 x 开始 y 结束, 且其中 x 和 y 保持 平衡 的字符串。 意思是,如果从左到右读这个字符串,对每次读到一个 x 就 +1 ,读到一个 y 就 -1, 最终结束处的那个 y 是第一个记数到 0 的 y。 举个例子,条目 %b() 可以匹配到括号平衡的表达式。 %f[set], 指 边境模式; 这个条目会匹配到一个位于 set 内某个字符之前的一个空串, 且这个位置的前一个字符不属于 set 。 集合 set 的含义如前面所述。 匹配出的那个空串之开始和结束点的计算就看成该处有个字符 '\0' 一样。
array = {"Lua", "Tutorial"} #注意lua索引是从1开始的,索引负数为逆序取索引
-- 初始化表 mytable = {} -- 指定值 mytable[1]= "Lua" -- 移除引用 mytable = nil -- lua 垃圾回收会释放内存 mytable = {} -- 普通表 mymetatable = {} -- 元表 setmetatable(mytable,mymetatable) -- 把 mymetatable 设为 mytable 的元表 setmetatable({}, { __index = other }) 1.在表中查找,如果找到,返回该元素,找不到则继续 2.判断该表是否有元表,如果没有元表,返回nil,有元表则继续。 3.判断元表有没有__index方法,如果__index方法为nil,则返回nil;如果__index方法是一个表,则重复1、2、3;如果__index方法是一个函数,则返回该函数的返回值。 __newindex 元方法用来对表更新,__index则用来对表访问 当你给表的一个缺少的索引赋值,解释器就会查找__newindex 元方法:如果存在则调用这个函数而不进行赋值操作,如果是表就更新此表。 操作符:__add,_sub,__mul,__div,__mod,__unm,__concat,__eq,__lt,__le等方法。 __call方法:可以使表+()执行元表的__call方法 __tostring:修改表的输出行为(类似python的__str)
#和python一样,一个程序多次导入只有第一次执行,多次导入不会多次执行。 模块的结构就是表的结构 require("<模块名>") 或require "<模块名>"或 local m = require("module") 也可以掉C包 Lua中写包不同,C包在使用以前必须首先加载并连接,在大多数系统中最容易的实现方式是通过动态连接库机制。 Lua在一个叫loadlib的函数内提供了所有的动态连接的功能。这个函数有两个参数:库的绝对路径和初始化函数。 例子如下 local path = "/usr/local/lua/lib/libluasocket.so" local f = loadlib(path, "luaopen_socket") —————————————————————— path = "C:\\windows\\luasocket.dll" ———————————————————— local f = assert(loadlib(path, "luaopen_socket")) f() -- 真正打开库
协程:
coroutine.create() 创建coroutine,返回coroutine, 参数是一个函数,当和resume配合使用的时候就唤醒函数调用
coroutine.resume() 重启coroutine,和create配合使用
coroutine.yield() 挂起coroutine,将coroutine设置为挂起状态,这个和resume配合使用能有很多有用的效果
coroutine.status() 查看coroutine的状态,coroutine的状态有三种:dead,suspend,running
coroutine.wrap() 创建coroutine,返回一个函数,一旦你调用这个函数,就进入coroutine,和create功能重复
coroutine.running() 返回正在跑的coroutine,一个coroutine就是一个线程,当使用running的时候,就是返回一个corouting的线程号
co = coroutine.create( function(i) print(i); end ) coroutine.resume(co, 1) -- 1 print(coroutine.status(co)) -- dead print("----------") co = coroutine.wrap( function(i) print(i); end ) co(1) print("----------") co2 = coroutine.create( function() for i=1,10 do print(i) if i == 3 then print(coroutine.status(co2)) --running print(coroutine.running()) --thread:XXXXXX end coroutine.yield() end end ) coroutine.resume(co2) --1 coroutine.resume(co2) --2 coroutine.resume(co2) --3 print(coroutine.status(co2)) -- suspended print(coroutine.running()) print("----------") echo: 第一次协同程序执行输出 1 10 foo 函数输出 2 main true 4 --分割线---- 第二次协同程序执行输出 r main true 11 -9 ---分割线--- 第三次协同程序执行输出 x y main true 10 结束协同程序 ---分割线--- main false cannot resume dead coroutine ---分割线---
file = io.open (filename [, mode]) mode=r,w,r+,w+,a,a+,+,b(+为可读写) 其中如果读文件后,文件长度为0,自动删除文件。 io.read()可以跟参数 *n 读取一个数字并返回它。例:file.read("*n") *a 从当前位置读取整个文件。例:file.read("*a") *l 默认 读取下一行,在文件尾 (EOF) 处返回 nil。例:file.read("*l") number 返回一个指定字符个数的字符串,或在 EOF 时返回 nil。例:file.read(5) io.tmpfile():返回一个临时文件句柄,该文件以更新模式打开,程序结束时自动删除 io.type(file): 检测obj是否一个可用的文件句柄 io.flush(): 向文件写入缓冲中的所有数据 io.lines(optional file name): 返回一个迭代函数,每次调用将获得文件中的一行内容,当到文件尾时,将返回nil,但不关闭文件 也可以使用:代替.