Lua 语言学习

Posted Just_for_Myself

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Lua 语言学习相关的知识,希望对你有一定的参考价值。

  详细讲解见菜鸟教程 Lua

 

一、数据类型

 1 -- 直接输出
 2 print("hello")
 3 
 4 
 5 -- 全局变量
 6 b = 11
 7 print(b)
 8 
 9 
10 
11 -- nil(空)
12 print(type(a))
13 -- 对于全局变量和table,nil 还有清空的作用
14 
15 
16 -- number(数字)
17 -- Lua 默认只有一种number类型 -- double(双精度)
18 
19 
20 -- string(字符串)
21 -- 字符串由一对双引号或单引号来表示
22 string1 = "this is string1"
23 string2 = this is string2
24 -- 在尝试对一个数字字符串进行算术操作时,Lua会尝试将数字字符串转换成数字
25 print("16" + 6)
26 -- 字符串连接 ..
27 print(16 .. 6)
28 -- 字符串长度 #
29 print(#string1)
30 
31 
32 -- table(表)
33 a = {}
34 -- 数组的索引可以为数字或者字符串
35 a["key"] = "value"
36 key = 10
37 a[key] = 22
38 -- 遍历
39 for k,v in pairs(a) do
40     print(k .. ":" .. v)
41 end
42 -- Lua里表的初始索引一般以 1 开始,而不是 0
43 -- table 长度不固定,会自动增加
44 
45 -- function(函数)
46 -- 函数名字f,包含一个参数 n
47 -- 主要实现阶乘的计算
48 function f(n)
49     if n==0 then
50         return 1
51     else
52         return n * f(n-1)
53     end
54 end
55 -- 调用函数
56 print(f(5))
57 -- 函数可以存储在一个变量中
58 f1 = f
59 print(f1(5))
60 
61 -- 匿名函数参数传递
62 -- 函数名 f1,有两个参数,其中第二个参数为一个函数
63 function f1(tab, f2)
64     for k, v in pairs(tab) do
65         -- 输出函数返回的值
66         print(f2(k, v))
67     end
68 end
69 
70 -- 新建表
71 tab = {"a", "b", "c"}
72 -- 调用函数,匿名函数作为参数传入
73 -- 注意key是从1开始的
74 f1(tab,
75     function(key, val) -- 匿名函数
76         return key .. " = " .. val
77     end
78 )
79 
80 
81 -- 变量
82 a = 5          -- 全局变量
83 local b = 10 -- 局部变量
84 -- Lua可以对多个变量同时赋值
85 x,y = 11,12
86 print(x .. "," .. y)
87 -- 交换x,y的值
88 x,y = y,x
89 print(x .. "," .. y)
90 -- 多值赋值也可用来接收函数返回的多个变量
91 function f()
92     return 11, 12
93 end
94 x,y = f()
95 print(x .. "," .. y)

 

 

 

 

二、循环

 1 -- while 语句
 2 a = 10
 3 -- 从10输出到20
 4 while(a < 20)
 5 do
 6     print("a = " .. a)
 7     a = a + 1
 8 end
 9 
10 
11 -- for 语句
12 -- 数值for循环
13 -- 从10变化到1,每次步长为-1
14 for i=10, 1, -1 do
15     print("i = " .. i)
16 end
17 -- 泛型for循环
18 days = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}
19 -- i为数组索引值,v是对应索引的数组元素值,ipairs为迭代器
20 for i,v in ipairs(days) do
21     print(v)
22 end
23 
24 
25 -- repeat...until 语句
26 -- 循环直到a>15
27 a = 10
28 repeat
29     print(a)
30     a = a + 1
31 until(a > 15)
32 
33 
34 -- break 语句
35 for a = 10,1,-1 do
36     print(a)
37     if(a < 5)
38     then
39         break    -- 当a<5,跳出循环
40     end
41 end

 

 

 

三、流程控制

 1 -- if...elseif..else 语句
 2 a = 100
 3 if(a == 10)
 4 then    -- a=10
 5     print("a 的值为 10")
 6 elseif(a == 20)
 7 then    -- a=20
 8     print("a 的值为 20")
 9 else    -- 没有匹配。注意不需要then
10     print("没有匹配的值")
11 end
12 
13 
14 -- if嵌套语句
15 a = 100
16 b = 200
17 if(a == 100)
18 then    -- a=100
19     if(b == 200)
20     then    -- a=100且b=200
21         print("a = " .. a .. " b = " .. b)
22     end
23 end

 

 

 

四、函数

 1 -- 多返回值
 2 -- 寻找最大值和最大值所在的位置
 3 function maximum(a)
 4     local mi = 1        -- 最大值位置
 5     local m = a[mi]        -- 最大值
 6     for k,v in ipairs(a) do
 7         if(v > m) then    -- 更大
 8             m = v
 9             mi = k
10         end
11     end
12     return m, mi        -- 输出最大值及其索引
13 end
14 
15 -- 输出最大值及其索引
16 print(maximum({8, 10, 13, 6, 15, 9}))
17 
18 -- 可变参数
19 -- 求不确定参数个数的平均值
20 function averge(...)
21     result = 0
22     -- 可变参数可以赋值给变量
23     local arg = {...}
24     for k,v in ipairs(arg) do
25         result = result + v
26     end
27     -- #可以获取...长度
28     print("总共传入 " .. #arg .. " 个数")
29     -- 返回平均值
30     return result/#arg
31 end
32 
33 -- 输出平均值
34 print("平均值为 " .. averge(10, 5, 3, 4, 5, 6))

 

 

 

五、运算符

 1 -- 算术运算符
 2 -- + - * / 加减乘除
 3 -- % 取余 ^ 乘幂 - 负号
 4 
 5 
 6 -- 关系运算符
 7 -- == 等于 ~= 不等于
 8 -- > < >= <= 大于 小于 大于等于 小于等于
 9 
10 
11 -- 逻辑运算符
12 -- and 逻辑与 or 逻辑或 not 非
13 
14 
15 -- 其他运算符
16 -- .. 连接两个字符串
17 -- # 返回字符串或表的长度

 

 

六、字符串

 1 -- 字符串大小写转换
 2 s = "Lua"
 3 print(string.upper(s))    -- 大写
 4 print(string.lower(s))    -- 小写
 5 
 6 
 7 -- 字符串查找与反转
 8 s = "Lua Tutorial"
 9 -- 查找字符串,若查找成功,返回头和尾,否则返回nil
10 print(string.find(s, "Tutorial"))
11 -- 字符串反转
12 reverses = string.reverse(s)
13 print(reverses)
14 
15 
16 -- 字符串格式化
17 date = 2
18 month = 1
19 year = 2014
20 -- 日期格式化
21 print(string.format("%02d/%02d/%04d", date, month, year))
22 -- 十进制格式化
23 print(string.format("%.3f", 1/3))
24 
25 
26 -- 字符与ASCII码的转换
27 -- 转换第一个字符
28 print(string.byte("Lua"))
29 -- 转换第三个字符
30 print(string.byte("Lua", 3))
31 -- 转换倒数第一个字符
32 print(string.byte("Lua", -1))
33 -- ASCII转字符
34 print(string.char(97))
35 
36 
37 -- 字符串长度
38 s = "Lua Tutorial"
39 print(string.len(s))
40 
41 
42 -- 模式匹配
43 -- 搜索 dd/mm/yy 格式的日期
44 s = "Deadline is 30/05/1999, firm"
45 date = "%d%d/%d%d/%d%d%d%d"
46 print(string.sub(s, string.find(s, date)))
47 -- 去除空格
48 -- gsub 返回的第二个参数为替代字符的个数
49 print(string.gsub(s, " ", ""))

 

 

 

七、数组

 1 -- 一维数组
 2 array = {}
 3 -- 初始化数组
 4 -- 注意数组下标默认从1开始,但是也可以自定义下标
 5 for i=-2, 2 do
 6     array[i] = i*2
 7 end
 8 -- 遍历数组
 9 for i=-2, 2 do
10     print(array[i])
11 end
12 
13 -- 二维数组
14 array = {}
15 maxRow = 3
16 maxColumn = 3
17 -- 初始化3行3列数组
18 for row=1,maxRow do
19     array[row] = {}
20     for col=1,maxColumn do
21         array[row][col] = row * col
22     end
23 end
24 -- 遍历数组
25 for row=1,maxRow do
26     for col=1,maxColumn do
27         print(array[row][col])
28     end
29 end

 

 

 

八、迭代器

 1 -- pairs和ipairs区别
 2 -- pairs 可以遍历集合的所有元素,即可以遍历集合中的所有key
 3 -- ipairs 按照索引升序遍历,索引中断停止遍历
 4 tab = {
 5 [1] = "a",
 6 [2] = "b",
 7 [4] = "c"    -- 注意索引值没有3
 8 }
 9 
10 -- pairs
11 -- 输出 a,b,c
12 for k, v in pairs(tab) do
13     print(v)
14 end
15 
16 -- ipairs
17 -- 只输出 a,b
18 for k, v in ipairs(tab) do
19     print(v)
20 end

 

 

九、表(table)

 1 -- 初始化表
 2 mytable = {}
 3 -- 指定值
 4 mytable[1] = "Lua"
 5 -- 移除引用
 6 -- 之后Lua垃圾回收会释放内存
 7 mytable = nil
 8 
 9 
10 -- table 连接
11 fruits = {"banana","orange","apple"}
12 -- 直接连接
13 print(table.concat(fruits))
14 -- 指定连接字符
15 print(table.concat(fruits, ","))
16 -- 指定要连接的字符串
17 print(table.concat(fruits, ", ", 2, 3))
18 
19 
20 -- 插入和删除
21 fruits = {"banana","orange","apple"}
22 -- 在末尾插入
23 table.insert(fruits, "watermelon")
24 print(table.getn(fruits))
25 -- 在指定位置插入
26 table.insert(fruits, 2, "pear")
27 print(fruits[2])
28 print(table.getn(fruits))
29 -- 删除指定位置的元素
30 print(table.remove(fruits, 4))
31 print(table.getn(fruits))
32 
33 
34 -- 排序
35 fruits = {"banana","orange","apple","grapes"}
36 print("排序前")
37 for k,v in ipairs(fruits) do
38     print(k,v)
39 end
40 
41 -- 排序,默认为升序
42 table.sort(fruits)
43 print("排序后")
44 for k,v in ipairs(fruits) do
45     print(k,v)
46 end
47 
48 
49 -- 注意使用 # 和 table.getn 其都会在索引中断的地方停止计数,
50 -- 而导致无法正确取得 table 的长度
51 -- 可以用以下的方法
52 function table_leng(t)
53   local leng=0
54   for k, v in pairs(t) do
55     leng=leng+1
56   end
57   return leng
58 end

 

 

十、模块

  模块代码如下:

 1 -- module.lua
 2 -- 定义一个名为 module 的模块
 3 module = {}
 4 
 5 -- 定义一个常量
 6 module.constant = "这是一个常量"
 7 
 8 -- 定义一个函数
 9 function module.func1()
10     io.write("这是一个公有函数!\n")
11 end
12 
13 local function func2()
14     print("这是一个私有函数!")
15 end
16 
17 function module.func3()
18     func2()
19 end
20 
21 return module

  调用模块代码如下:

1 -- 加载模块
2 -- 返回一个由模块常量和函数组成的table
3 local m = require("module")
4 
5 print(m.constant)    -- 访问模块常量
6 m.func3()            -- 访问模块函数

 

 

十一、协同程序

 1 -- 协同程序
 2 -- 创建协程,resume时唤醒函数
 3 co = coroutine.create(
 4     function(i)
 5         print(i);
 6     end
 7 )
 8 
 9 -- 重启协程,并传入参数
10 coroutine.resume(co, 1)   -- 1
11 -- 输出协程状态
12 print(coroutine.status(co))  -- dead
13 
14 print("----------")
15 
16 -- 作用与create一样
17 co = coroutine.wrap(
18     function(i)
19         print(i);
20     end
21 )
22 
23 co(1)
24 
25 print("----------")
26 
27 -- create时就是在新线程中注册一个事件
28 co2 = coroutine.create(
29     function()
30         for i=1,10 do
31             print(i)
32             if i == 3 then
33                 print(coroutine.status(co2))  --running
34                 print(coroutine.running()) --thread:XXXXXX
35             end
36             -- 遇到yield协程会暂时挂起
37             coroutine.yield()
38         end
39     end
40 )
41 
42 -- resume会重新激活事件
43 coroutine.resume(co2) --1
44 coroutine.resume(co2) --2
45 coroutine.resume(co2) --3
46 
47 print(coroutine.status(co2))   -- suspended
48 print(coroutine.running())
49 
50 print("----------")

 

 

十二、文件 I/O

 1 -- 文件 I/O
 2 -- 打开文件
 3 file = io.open("协同程序.lua", "r")
 4 
 5 -- 输出文件第一行
 6 print(file:read())
 7 
 8 -- 获取倒数第10个字符位置
 9 file:seek("end",-10)
10 -- 读取后10个字符
11 print(file:read("*a"))
12 
13 -- 关闭文件
14 file:close()
15 
16 -- 以附加的方式打开只写文件
17 file = io.open("协同程序.lua", "a")
18 
19 -- 在文件末尾写入字符串
20 file:write("-- test io")

 

 

十三、面向对象

 1 -- 面向对象
 2 -- Shape 类,包含一个属性 area
 3 Shape = {area = 0}
 4 
 5 -- 构造方法
 6 function Shape:new (o, side)
 7     o = o or {}
 8     setmetatable(o, self)
 9     self.__index = self
10     side = side or 0
11     self.area = side*side
12     return o
13 end
14 
15 -- 输出形状面积
16 function Shape:printArea()
17     print("面积为:", self.area)
18 end
19 
20 -- 创建对象
21 myShape = Shape:new(nil, 10)
22 -- 输出面积
23 myShape:printArea()        -- 100
24 
25 
26 -- 继承
27 -- 长方形
28 Rectangle = Shape:new()
29 -- 派生类构造方法
30 function Rectangle : new(o, length, breadth)
31     o = o or Shape:new(o)
32     setmetatable(o, self)
33     self.__index = self
34     self.area = length * breadth
35     return o
36 end
37 
38 -- 函数重写
39 function Rectangle : printArea()
40     print("长方形面积为:", self.area)
41 end
42 
43 -- 创建一个长方形对象
44 myRectangle = Rectangle:new(nil, 10, 20)
45 -- 输出长方形面积
46 myRectangle:printArea()    -- 200

以上是关于Lua 语言学习的主要内容,如果未能解决你的问题,请参考以下文章

lua错误:尝试调用nil值(字段'getn')

lua是啥语言

Lua脚本语言简单学习

lua 学习之编译

Lua 代码是如何跑起来的

wireshark插件开发 - Lua插件解析