Lua官网
Lua官方文档
Lua5.4参考指南
Lua5.3参考手册(中文版)
Lua菜鸟教程
Lua在线编辑器


Lua基本语法
Lua数据类型
Lua变量
Lua流程控制
Lua函数
Lua运算符
Lua字符串
Lua数组
Lua迭代器
Lua table(表)
Lua模块与包
Lua元表(Metatable)
Lua协同程序(coroutine)
Lua文件I/O
Lua错误处理
Lua调试(Debug)
Lua垃圾回收
Lua面向对象


一、变量类型

  1. --未赋值的变量为nil
  2. --声明字符串变量(单引号或双引号皆可)
  3. --声明number
  4. s = 'my age is: '
  5. i = 16
  6. b = true
  7. print(s, i, b)
  8.  
  9. --字符串也可以这样写[[字符串内容]]
  10. s = [[s1: hello world!]]
  11. print(s1)
  12.  
  13. --声明table变量(相当于字典),没keyvalue用索引访问(索引从1开始)
  14. tab = {web = "www.baidu.com", QQ = 123456, b = true, "no-key-value"}
  15. print("table: ", tab["web"], tab["QQ"], tab["b"], tab[1])
  16.  
  17. s = "25"
  18. i = 26
  19. --字符串转数字,数字转字符串
  20. print(tonumber(s), tostring(i))
  21.  
  22.  
  23. --创建一个函数
  24. function fun(name)
  25. print("my name is "..name);
  26. end
  27.  
  28. fun("tom")

运行结果
>lua -e "io.stdout:setvbuf 'no'" "test.lua"
my age is:  16 true
s: hello world!
table:   www.baidu.com  123456 true no-key-value
25 26
my name is tom
>Exit code: 0

局部变量 local

示例1

  1. x = 5
  2. for i = 1, 10000 do
  3. local x = i
  4. end
  5. print(x)


输出 5

========================================================================================

for循环

  1. --数字for循环
  2. for i = 0, 10, 2 do
  3. print(i)
  4. end
  5.  
  6. --泛型for循环,ipairs()是数组的迭代器
  7. arr = {"a", "b", "c", "d"}
  8. for i, v in ipairs(arr) do
  9. print("arr["..i.."]="..v)
  10. end

 

运行结果

>lua -e "io.stdout:setvbuf 'no'" "test.lua"
0
2
4
6
8
10
arr[1]=a
arr[2]=b
arr[3]=c
arr[4]=d
>Exit code: 0

 

while循环

  1. do
  2. local i = 1
  3. local n = 10
  4. while (i < n) do
  5. print(i)
  6. i = i + 1
  7. end
  8. end

 

repeat循环

  1. i = 1
  2. repeat
  3. i = i + 1
  4. --当until(真)时跳出循环
  5. until(i > 10)

========================================================================================

数学运算操作符
支持:加、减、乘、除、取模、幂

  1. a = 5
  2. b = 6
  3. c = 7
  4. d = 8
  5. --支持: 加、减、乘、除、取模、幂
  6. r = (a + b) * (a - b) / c % 8 + a^(-0.5)
  7. print("r="..r)

========================================================================================

可见性规则(闭包)

  1. a = {}
  2. local x = 20
  3. --创建10个函数闭包
  4. --这些闭包中的每一个都使用了不同的y变量,而它们又共享了同一份x
  5. for i=1,10 do
  6. local y = 0
  7. a[i] = function () y=y+1; return x+y end
  8. end
  9. for i=1,10 do
  10. print(a[i]())
  11. end


输出

21
21
21
21
21
21
21
21
21
21

==========================================================================================

实现继承
__index、setmetatable()

  1. --示例1: 继承
  2. local Car = {}
  3. Car.__index = Car;
  4. function Car:run()
  5. print("Car:run()")
  6. end
  7.  
  8. local SuvCar = {}
  9. --SuvCar继承Car
  10. setmetatable(SuvCar, Car)
  11. print(SuvCar.run())
  12.  
  13. --示例2: 继承
  14. local Car1 = {}
  15. function Car1:new(o)
  16. o = o or {}
  17. --o继承Car1
  18. setmetatable(o, { __index = Car1 })
  19. return o;
  20. end
  21.  
  22. function Car1:run()
  23. print("Car1:run()")
  24. end
  25.  
  26. --SuvCar1继承Car1
  27. local SuvCar1 = Car1.new()
  28. function SuvCar1:run1()
  29. print("SuvCar1:run1()")
  30. end
  31.  
  32. print(SuvCar1.run())
  33. print(SuvCar1.run1())
输出 
Car:run() 
Car1:run()
SuvCar1:run1()

========================================================================================

协程

  1. function foo (a)
  2. print("foo", a)
  3. return coroutine.yield(2*a)
  4. end
  5. co = coroutine.create(function (a,b)
  6. print("co-body", a, b)
  7. local r = foo(a+1)
  8. print("co-body", r)
  9. local r, s = coroutine.yield(a+b, a-b)
  10. print("co-body", r, s)
  11. return b, "end"
  12. end)
  13. print("main", coroutine.resume(co, 1, 10))
  14. --[[
  15. 上句输出
  16. co-body 1 10
  17. foo 2
  18. main true 4
  19. --]]
  20.  
  21. --resume方法的参数作为yield()的返回
  22. --yield方法的参数作为resume方法的返回
  23. print("main", coroutine.resume(co, "r"))
  24. --[[
  25. 上句输出
  26. co-body r
  27. main true 11 -9
  28. --]]
  29. print("main", coroutine.resume(co, "x", "y"))
  30. --[[
  31. 上句输出
  32. co-body x y
  33. main true 10 end
  34. --]]
  35. print("main", coroutine.resume(co, "x", "y"))
  36. --[[
  37. 上句输出
  38. main false cannot resume dead coroutine
  39. --]]
输出:
co-body 1 10
foo 2
main true 4
co-body r
main true 11 -9
co-body x y
main true 10 end
main false cannot resume dead coroutine


========================================================================================

错误处理

  1. print("--------test pcall------")
  2. function test()
  3. print("hello world")
  4. error("wrong value")
  5. end
  6. --pcall,以保护模式调用函数,出错时不打印堆栈信息
  7. print( pcall(test) )
  8.  
  9. print("--------test xpcall------")
  10. function errhander(e)
  11. print("error info: " .. e)
  12. print("stack info: " .. debug.traceback("current 2 stack: " ,2))
  13. end
  14. function ef()
  15. error("wrong value")
  16. end
  17. --xpcall,以保护模式调用函数,出错时调用回调方法并打印堆栈信息
  18. print( xpcall(ef,errhander) )


输出: --------test pcall------
hello world
false D:\test.lua:4: wrong value
--------test xpcall------
error info: D:\test.lua:15: wrong value
stack info: current 2 stack:
stack traceback:
[C]: in function 'error'
D:\test.lua:15: in function 'ef'
[C]: in function 'xpcall'
D:\test.lua:18: in main chunk
[C]: in ?
false nil

========================================================================================

环境/全局变量: _ENV

  1. --_ENV是一个普通的全局table,所有的全局变量都会放到_ENV
  2. --print(type(_ENV))
  3. --定义一个全局变量
  4. my_gobal_var = 123
  5. --访问全局变量
  6. print(my_gobal_var)
  7. print(_ENV.my_gobal_var)
  8. print(_ENV["my_gobal_var"])
  9.  
  10. --打印所有全局变量
  11. for n in pairs(_ENV) do print(n) end
  12.  
  13. --判断是否定义了my_gobal_var变量
  14. if my_gobal_var ~= nil then
  15. print("exits my_gobal_var") --这里会被执行到
  16. end
  17.  
  18. --覆盖默认环境
  19. _ENV = {print=print}
  20. if my_gobal_var == nil then
  21. print("not exits my_gobal_var") --这里会被执行到
  22. end

输出:
123
123
123
setmetatable
os
assert
utf8
rawequal
rawset
dofile
loadfile
rawget
require
collectgarbage
my_gobal_var
io
table
pcall
math
package
coroutine
tostring
select
pairs
ipairs
rawlen
next
error
arg
type
print
tonumber
debug
xpcall
string
load
_G
getmetatable
_VERSION
bit32
exits my_gobal_var
not exits my_gobal_var
========================================================================================

table.maxn()
返回table中最大正数索引

  1. t = {t1="a", t2="b", "c", "d", "e", "f", t3="g", "h"}
  2. --连接table中的索引元素
  3. --concat(table, 分隔符, 起始位置, 结束位置)
  4. tab = table.concat(t, "-", 2, 3);
  5. print(tab) --输出 d-e
  6. print(_VERSION)
  7. if _VERSION == "Lua 5.3" then
  8. print("lua version is 5.3")
  9. --lua5.3已经移除了maxn函数,需要自己实现
  10. --函数功能: 返回tabel中最大的正数索引
  11. table.maxn = function(tab)
  12. local n = 0
  13. for k,v in pairs(tab) do
  14. if type(k) == "number" and k > n then
  15. n = k
  16. end
  17. end
  18. return n
  19. end
  20. end
  21.  
  22. local n = table.maxn(t)
  23. table.insert(t, n+1, "i")
  24.  
  25. for k,v in pairs(t) do print(k,v) end
  26. print("maxn="..table.maxn(t))

输出:
d-e
Lua 5.3
lua version is 5.3
1       c
2       d
3       e
4       f
5       h
6       i
t3      g
t1      a
t2      b
maxn=6
========================================================================================

table.remove()
删除指定位置的元素

  1. t = {t1="a", t2="b", "c", "d", "e", "f", t3="g", nil, "h", "i", nil}
  2. print("maxn="..#t)
  3. --删除索引为1的元素,后面的元素会自动往前移
  4. table.remove(t, 1)
  5. --删除索引最大的元素
  6. table.remove(t, #t)
  7. --删除t2
  8. t.t2 = nil
  9. for k,v in pairs(t) do print(k,v) end
  10. --安全删除所有以数字索引为key的元素,必须从后往前删
  11. --只会删除找到的第一段连续索引元素
  12. for i = #t, 1, -1 do
  13. table.remove(t, i)
  14. end
  15. print("deleted all index element")
  16. for k,v in pairs(t) do print(k,v) end

输出
maxn=7
1       d
2       e
5       h
6       i
t1      a
t3      g
deleted all index element
5       h
6       i
t1      a
t3      g

========================================================================================

table.pack()、table.unpack()

  1. t = table.pack(1,"a",2,3) --打包
  2. print("#t="..#t)
  3. print("t.n="..t.n)
  4. for k,v in pairs(t) do print(k,v) end
  5. print("----unpack----")
  6. local a,b,c,d = table.unpack(t) --解包
  7. print(a,b,c,d)
  8. print(table.unpack(t, 2))
  9. print(table.unpack(t, 2, 3))

输出
#t=4
t.n=4
1       1
2       a
3       2
4       3
n       4
----unpack----
1       a       2       3
a       2       3
a       2

========================================================================================

table.move()、table.sort()

  1. t1 = {1, 2, 3, k1="abc"}
  2. t2 = {4, 5, 6, k2="def", 7}
  3. --将t1中的全部索引元素复制到t2
  4. table.move(t1, 1, #t1, #t2+1, t2)
  5. for k, v in pairs(t2) do print(k, v) end
  6.  
  7. --注意: 比较函数实际上是重载了<号,所以当>=时都要返回false才行
  8. table.sort(t2, function(a, b)
  9. --if(a < b) then return true end --升序
  10. if(a > b) then return true end --降序
  11. return false
  12. end
  13. )
  14. print("--------sort-------")
  15. for k, v in pairs(t2) do print(k, v) end

输出
1       4
2       5
3       6
4       7
5       1
6       2
7       3
k2      def
--------sort-------
1       7
2       6
3       5
4       4
5       3
6       2
7       1
k2      def
========================================================================================

utf8

  1. os.execute("chcp 936") --cmd中设置代码页为GBK
  2. --os.execute("chcp 65001") --cmd中设置代码页为UTF-8
  3. --每个中文字符占3个字节, Unicode码写法"\u{4E2D}\u{6587}"
  4. local input = "中文Engish" --等效于local input = "\u{4E2D}\u{6587}Engish"
  5. print("len="..utf8.len(input))
  6.  
  7. print("---------utf8.codes-------")
  8. --遍历字符串中的所有字符
  9. for p, c in utf8.codes(input) do
  10. print(p, c, utf8.char(c))--打印出字符中Unicode
  11. end
  12.  
  13. print("---------utf8.codepoint----")
  14. --获取并打印前两个中文字符(总共占6字节)
  15. print(utf8.codepoint(input, 1, 6))
  16.  
  17. print("---------utf8.offset----")
  18. --返回第2个字符的开始位置(按字节数),从第1个位置开始统计
  19. print(utf8.offset(input, 2, 1))
  20.  
  21. print("---------utf8.charpattern----")
  22. --打印所有匹配的UTF-8字符
  23. for c in string.gmatch(input, utf8.charpattern) do
  24. print(c)
  25. end

输出
活动代码页: 936
len=8
---------utf8.codes-------
1       20013   涓
4       25991   鏂
7       69      E
8       110     n
9       103     g
10      105     i
11      115     s
12      104     h
---------utf8.codepoint----
20013   25991
---------utf8.offset----
4
---------utf8.charpattern----


E
n
g
i
s
h
========================================================================================

string

  1. local s = "Helo,World"
  2. local s1 = "from=world, to=lua"
  3. --打印每个字符的ANSI
  4. print("byte:", string.byte(s, 1, -1))
  5. --ANSI码转字符串
  6. print("char:", string.char(string.byte(s, 1, -1)))
  7. --搜索第一个匹配的标点符号,第四个参数为true会关闭模式匹配
  8. print("find:", string.find(s, "%p", 1, false))
  9. --格式化字符串
  10. print("format:", string.format('%s,%g,%i', "input-string", 0.5, 1))
  11. --搜寻所有匹配的子串
  12. for k, v in string.gmatch(s1, "(%w+)=(%w+)") do
  13. print("gmatch:", k, v)
  14. end
  15. --查找并替换
  16. local repl = {name="lua", version="5.3"}
  17. print("gsub", string.gsub("$name-$version.tar.gz", "%$(%w+)", repl)) --替换全部匹配项
  18. print("gsub", string.gsub("$name-$version.tar.gz", "%$(%w+)", repl, 1)) --替换第1个匹配项
  19. print("gsub", string.gsub(s, "(%w+),(%w+)", "%2,%1"))--%1~%9代表匹配到的子项,%0代表这里的s
  20. local s = string.gsub(s, "^%s*(.-)%s*$", "%1") --去除s左右空白字符
  21. --查找匹配
  22. print("match:", string.match(s, "%w+"), 1)--返回第一个匹配串及开始位置
  23. --字符串长度
  24. print("len", string.len(s))
  25. --转成小写
  26. print(string.lower(s))
  27. --转成大写
  28. print(string.upper(s))
  29. --以小端方式打包参数
  30. local fmt = "<I4I4s4f" --格式化参数详见文档
  31. local p = string.pack(fmt, 100, 200, "hello", 0.1)
  32. print("packsize:", string.packsize(p))--输出字节数
  33. print("unpack:", string.unpack(fmt, p, 1)) --解包
  34. --用指定分割符连接字符串
  35. print("rep:", string.rep("ss", 5, "-"))
  36. --反转字符串
  37. print("reverse:", string.reverse(s))
  38. --返回子串
  39. print("sub:", string.sub(s, 1, 5))
  40. --序列化与反序列化函数
  41. function fun()
  42. print("string.dump test")
  43. end
  44. --将函数序列化为二进制,false代表包含调试信息
  45. local b = string.dump(fun, false)
  46. --对函数反序列化
  47. local f = load(b)
  48. f()

输出
byte:   72      101     108     111     44      87      111     114     108
100
char:   Helo,World
find:   5       5
format: input-string,0.5,1
gmatch: from    world
gmatch: to      lua
gsub    lua-5.3.tar.gz  2
gsub    lua-$version.tar.gz     1
gsub    World,Helo      1
match:  Helo    1
len     10
helo,world
HELO,WORLD
packsize:       8
unpack: 100     200     hello   0.10000000149012        22
rep:    ss-ss-ss-ss-ss
reverse:        dlroW,oleH
sub:    Helo,
string.dump test
========================================================================================

__pairs

  1. local t = {1, 2, nil, 3}
  2. print("------ipairs------")
  3. --ipairs遇到nil就会停止迭代
  4. for k, v in ipairs(t) do
  5. print("ipairs:", k, v)
  6. end
  7.  
  8. print("------pairs------")
  9. --pairs会跳过nil继续迭代
  10. for k, v in pairs(t) do
  11. print("pairs:", k, v)
  12. end
  13.  
  14. --自定义表的迭代函数
  15. local pairsfunc = function(tbl, key)
  16. local nk, nv = next(tbl, key) --返回下一对k-v
  17. if nk then
  18. nv = tbl[nk]
  19. end
  20. return nk, tostring(nv)..'p' --对返回的值做点改变
  21. end
  22.  
  23. local mt = {}
  24. mt.__pairs = function(tbl, key)
  25. return pairsfunc, tbl, nil
  26. end
  27. setmetatable(t, mt) --给t设置元表
  28.  
  29. print("------__pairs------")
  30. --会调用t的元表中的__pairs函数
  31. for k, v in pairs(t) do
  32. print("pairs:", k, v)
  33. end

输出
------ipairs------
ipairs: 1       1
ipairs: 2       2
------pairs------
pairs:  1       1
pairs:  2       2
pairs:  4       3
------__pairs------
pairs:  1       1p
pairs:  2       2p
pairs:  4       3p
========================================================================================

rawequal()、rawget()、rawlen()、select()

  1. local t = {1, 2, nil, 3}
  2. local t1 = t
  3. local s = "hello,world"
  4. local s1 = "hello,world"
  5. print("rawequal:", rawequal(t, t1)) --表比较引用
  6. print("rawequal:", rawequal(s, s1)) --字符串比较值
  7. print("rawget:", rawget(t, 1)) --获取元素
  8. print("rawlen:", rawlen(t), rawlen(s)) --获取长度
  9. rawset(t, "k", "v") --设值
  10. local params_count = select("#", 1, 2, 3, 4, 5, "p") --返回参数个数
  11. print("select:", params_count)
  12. local param = select(6, 1, 2, 3, 4, 5, "p") --返回第6个参数
  13. print("select:", param)

输出
rawequal:       true
rawequal:       true
rawget: 1
rawlen: 4       11
select: 6
select: p
========================================================================================

collectgarbage()

  1. print("isrunning:", collectgarbage("isrunning"))
  2. print("stop:", collectgarbage("stop"))
  3. print("isrunning:", collectgarbage("isrunning"))
  4. print("restart:", collectgarbage("restart"))
  5. print("isrunning:", collectgarbage("isrunning"))
  6. print("count:", tostring(collectgarbage("count")).."kb")
  7. print("step:", collectgarbage("step", 10))
  8. print("step:", collectgarbage("step", 10))
  9. --获取lua占用的内存数(单位kb)
  10. print("count:", tostring(collectgarbage("count")).."kb")
  11. --设置步进倍率为内存分配的2倍速度
  12. print("setstepmul:", collectgarbage("setstepmul", 200))
  13. --设置间歇率,当总使用内存达到之前的2倍时开始新的一轮收集
  14. print("setpause:", collectgarbage("setpause", 200))
  15. --做一次完整的垃圾收集循环,collect是默认选项
  16. print("collect:", collectgarbage("collect"))
  17. --步长设置大点希望一步就执行完收集工作
  18. print("step:", collectgarbage("step", 60))

输出
isrunning:      true
stop:   0
isrunning:      false
restart:        0
isrunning:      true
count:  25.9775390625kb
step:   false
step:   true
count:  24.50390625kb
setstepmul:     200
setpause:       200
collect:        0
step:   true
========================================================================================

函数

  1. --定义全局函数
  2. function gfun()
  3.  
  4. end
  5.  
  6. --定义局部函数
  7. local function locfun()
  8.  
  9. end
  10.  
  11. local Foo = {}
  12. Foo.name = "Job"
  13. --定义局部函数
  14. function Foo.fun(...)
  15. local tbl = {...} --以参数为内容创建一张表
  16. print(tbl[1])
  17. local p1 = select(1, ...) --获取第1个参数
  18. print("Foo.fun:", p1, ...)
  19. return ...
  20. end
  21. --定义局部函数
  22. Foo.fun1 = function(...)
  23. print("fun1")
  24. end
  25. --定义局部函数,self参数是个隐藏参数,会自动传入
  26. function Foo:fun2(x, y)
  27. print("fun2:", "x="..tostring(x), "y="..tostring(y), "name="..self.name)
  28. end
  29. --定义局部函数
  30. function Foo.fun3(self, x, y)
  31. print("fun3:", "x="..tostring(x), "y="..tostring(y), "name="..self.name)
  32. end
  33. print("Foo.fun: return ", Foo.fun(1, 2, 3))
  34. --把函数调用括起来只接收返回的第一个值
  35. print("(Foo.fun): return ", (Foo.fun(1, 2, 3)))
  36.  
  37. --函数写在前面只会返回一个值
  38. local a, b, c, d = Foo.fun(1,2,3), 4
  39. print("return1:", a, b, c, d)
  40. --函数会返回所有值
  41. local a, b, c, d = 4, Foo.fun(1,2,3)
  42. print("return2:", a, b, c, d)
  43.  
  44. --调用冒号定义的函数
  45. Foo.fun2(Foo, 10, 20) --必须显示传入self
  46. Foo:fun2(10, 20) --会自动隐式传入self
  47. --调用点号定义的函数
  48. Foo.fun3(Foo, 10, 20) --必须显示传入self

输出
1
Foo.fun:        1       1       2       3
Foo.fun: return         1       2       3
1
Foo.fun:        1       1       2       3
(Foo.fun): return       1
1
Foo.fun:        1       1       2       3
return1:        1       4       nil     nil
1
Foo.fun:        1       1       2       3
return2:        4       1       2       3
fun2:   x=10    y=20    name=Job
fun2:   x=10    y=20    name=Job
fun3:   x=10    y=20    name=Job
========================================================================================

UpValue

  1. function fun1()
  2. local a = 1 --外层变量就是内嵌函数的UpValue
  3. local fun2 = function()
  4. a = a + 1
  5. return a
  6. end
  7. return fun2
  8. end
  9. --内嵌函数脱离外层函数时依然可以访问UpValue
  10. local f1 = fun1()
  11. print("f1:", f1())
  12. print("f1:", f1())
  13. --
  14. local f2 = fun1()
  15. print("f2:", f2())
  16. print("f2:", f2())

输出
f1:     2
f1:     3
f2:     2
f2:     3

示例
string = "Lua Tutorial"
-- 查找字符串
print(string.find(string,"Tutorial"))
reversedString = string.reverse(string)
print("新字符串为",reversedString)

示例
string = "Lua Tutorial" 
-- 查找字符串 
print(string.find(string,"Tutorial"))
reversedString = string.reverse(string)
print("新字符串为",reversedString)
以上代码执行结果为:
5    12
新字符串为    lairotuT auL
Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号