lua学习笔记
Posted 森明帮大于黑虎帮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lua学习笔记相关的知识,希望对你有一定的参考价值。
文章目录
- 1、lua语言介绍
- 2、开发环境配置与hello world
- 3、变量命名规范
- 4、基本数据类型一
- 5、基本数据类型二:function
- 6、基本数据类型三 : table
- 7、基本运算符(一)
- 8、基本运算符(二)
- 9、流程控制 - 判断
- 10、流程控制循环(一) ->while和repeat
- 11、流程控制循环goto语句
- 12、流程控制循环(二) ->数值for和范围for ipairs
- 13、流程控制循环(三) -> pairs
- 14、table -> array
- 15、table操作函数
- 16、string常用api
- 17、function常见表示形式
- 18、table中的function
- 19、用select处理可变参数
- 20、用pack处理可变参数
- 21、lua中闭包 (closure)的实现
- 22、用闭包 (closure)实现ipairs迭代器
- 23、元表和元方法(一)
- 24、元表和元方法(二)
- 25、元表和元方法(三)
- 26、面向对象 self
- 27、面向对象自索引
- 28、面向对象自索引实现继承
- 29、面向对象类的实例化
- 30、面向对象多重继承
- 31、面向对象重写
- 32、面向对象成员私有化
- 33、协程(coroutine)
- 34、协程(coroutine)双循环切换
- 35、协程(coroutine)生产者消费者模型
- 36、文件操作
- 37、包(模块)管理
- 38、操作mysql数据库
- 39、操作redis缓存
- 40、全局环境变量和环境隔离
1、lua语言介绍
1. 1 语言介绍
-
Lua 是一个小巧的脚本语言。 其设计目的是为了通过灵活嵌入应用程序中从而为应用程序提供灵活的扩展和定制功能。
-
Lua由标准C编写而成,几乎在所有操作系统和平台上都可以编译,运行。
-
Lua并没有提供强大的库,这是由它的定位决定的。
-
所以Lua不适合作为开发独立应用程序的语言。Lua 有一个同时进行的JIT项目,提供在特定平台上的即时编译功能。
-
Lua由标准C编写而成,代码简洁优美,几乎在所有操作系统和平台上都可以编译,运行。
-
一个完整的Lua解释器不过200k,在所有脚本引擎中,Lua的速度是最快的。
-
这一切都决定了Lua是作为嵌入式脚本的最佳选择。
速度快、跨平台、开源、即时编译。
1.2 lua语言应用场景
- 游戏开发-用来做热更。
- 独立软件应用脚本。 Photoshop
- Web开发 应用脚本。
- WEB服务器中间件。 nginx支持扩展,lua写个扩展
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ChmuNnvi-1665330518827)(C:\\Users\\hp\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220925011711411.png)]
-
扩展和数据库操作脚本插件如:MySQL Proxy 和 MySQL WorkBench。
-
缓存操作脚本。 秒杀系统,用lua把一个非原子操作变成原子操作、锁。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ti87pIWg-1665330518830)(C:\\Users\\hp\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220925011617505.png)]
-
安全系统,如入侵检测系统。
百度百科:https://baike.baidu.com/item/lua
2、开发环境配置与hello world
2.1 开发环境配置
- 下载源代码包。
- 编译。
- 测试版本:lua -v。
windows下载网址:https://www.lua.org/download.html
Lua是用纯ANSI实现的,可以在所有有ANSI C编译器的平台上不加修改地编译。Lua也可以像C++一样干净地编译。
Lua非常容易构建和安装。有详细说明但是这里有一个简单的终端会话,它下载当前版本的Lua并在Linux中编译它:
Linux下载编译指令:
curl -R -O http://www.lua.org/ftp/lua-5.4.4.tar.gz
tar zxf lua-5.4.4.tar.gz
cd lua-5.4.4
make all test
运行上面四条指令之后出现:lua与luac表明编译成功。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-38PyICIJ-1665330518831)(C:\\Users\\hp\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220925020632089.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zzwRXbuc-1665330518831)(C:\\Users\\hp\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220925020656065.png)]
lua是运行lua文件,luac与编译lua文件。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jNmGolqG-1665330518832)(C:\\Users\\hp\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220925020740254.png)]
-
luac -o outfilename sourcefilename.lua 是给sourcefilename.lua起个名字叫 outfilename。
-
g++/gcc -o outfilename sourcefilename.cpp。
-
两者非常类似。
2.2 输出hello world
只需要用打印函数print就可以:
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> print (hello world)
stdin:1: ')' expected near 'world'
> print hello world
stdin:1: '=' expected near 'hello'
> print ('hello world')
hello world
> print ('hello world')
3、变量命名规范
--[[
变量命名规范:
lua弱语言类型(动态语言类型),定义变量的时候,不需要类型修饰。
而且,变量随时都可以改变。
每行代码结束的时候,要不要分号都可以。
变量名由数字、字母、下划线组成,不能由数字开头,也不能是保留字(关键字),而且也不可以是特殊字符。
变量名区分大小写,避免创建下划线开头加大写字母组成的变量名。因为可能会有命名冲突 --VERSION 这就是lua里面的关键字。
变量类型
变量分为三种类型,全局变量、局部变量、表字段
默认创建的都是全局变量,局部变量用local修饰
代码块(作用域)
do
....
end
]] --
代码示例:
a=123 --int
print(a)
a="abc" --string
print(a)
a=true --bool
print(a)
a123=123
print(a123)
a_123=123
print(a_123)
_a=123
print(_a)
_123_a=123
print(_123_a)
--这里由数字开头 123_a=123 --非法的
A123=456
print(A123)
abc=123
print(abc)
ABC=123
print(123)
local xyz=123 --局部变量
print(xyz)
--[[
int a=123; 这里是C/C++语言中的作用域
]] --
abcd=123
--代码块
do
xyz=123
local XYZ=123
print(abcd)
print(xyz)
print(XYZ)
end
print("\\n")
print(abcd)
print(xyz)
print(XYZ)
输出结果:
PS D:\\lua代码> & 'c:/Users/hp/.vscode/extensions/actboy168.lua-debug-1.59.0-win32-x64/runtime/win32-x64/lua54/lua.exe' '-e' 'dofile[[c:/Users/hp/.vscode/extensions/actboy168.lua-debug-1.59.0-win32-x64/script/launch.lua]];DBG[[16296,ansi]]' 'D:\\lua代码/变量命名规范/变量命名规范.lua'
123
abc
true
123
123
123
123
456
123
123
123
123
123
123
123
123
nil
PS D:\\lua代码>
4、基本数据类型一
--[[
基本数据类型
Lua 中有八种基本类型: nil、boolean、number、 string、function、userdata、 thread和table
number 包括整型和浮点型
string 单引号,双引号都表示string,不管是单引号,双引号,单个字符多个字符
转义 用反斜杠 \\n 换行符 \\t 制表符
原始输出用 [[ \\] \\]
userdata 自定义数据格式
thread 协程
table 表
在lua 中,只有false 和 nil 才表示假
0和空串表示真
库函数type返回一个描述给定值类型的字符串
type (v)返回其唯一参数的类型,编码为字符串
]]--
a=nil
print(type(nil))
print(type(true))
print(type(boolean))
print(type(123))
print(type(111))
print(type(000))
print(type(1.123123))
--不管是单引号,双引号,单个字符多个字符
a='abc'
b='a'
c="abc"
d="a"
print(type(a))
print(type(b))
print(type(c))
print(type(d))
a='a\\nb\\ncd\\tfd'
print(a)
b=[['a\\nb\\ncd\\tfd']]
print(b)
print(type(type))
print(type(print))
print(type())
a1=nil
if a1 then
print("真")
else
print("假")
end
b1=0
if b1 then
print("真")
else
print("假")
end
c1=""
if c1 then
print("真")
else
print("假")
end
输出结果:
nil
boolean
nil
number
number
number
number
string
string
string
string
a
b
cd fd
'a\\nb\\ncd\\tfd'
function
function
table
假
真
真
PS D:\\lua代码>
5、基本数据类型二:function
--[[
基本数据类型
Lua有8种数据类型:nil,boolean,number,string,function,userdata,thread和table
function 在lua中一个基本的数据类型是第一类值
格式
function funcName()
...
end
传参或返回值,都很自由
function 可以作为参数被传递,也可以作为值被赋值给另一个变量
]] --
--c++
--void func(int a,int b);
--void func(int a,int b)return a+b;
--lua
function Func1()
print("this is func1")
end
Func1()
--传参
function Func2(a, b, c)
print(a, b, c)
end
Func2(1, "lua", 'aa')
function Func3(a, b, c)
print(1, 'a', "vb", 1, 3)
end
Func3()
--可变参
function Func5(...)
end
--函数当右值
--把匿名函数赋值给变量
Sum1 = function(a, b)
return a + b
end
print(Sum1(10,20))
Sum2=Sum1
print(Sum2(100,200))
--当做其他函数的参数
function Func6(functionName,a,b)
return functionName(a,b)
end
print(Func6(Sum1,1000,2000))
function Func7(a,b)
return a+b
end
print(Func6(Func7,10000,20000))
输出结果:
this is func1
1 lua aa
1 a vb 1 3
30
300
3000
30000
PS D:\\lua代码>
6、基本数据类型三 : table
--[[
基本数据类型
Lua中有8中数据类型:nil boolean number string function table userdata thread
table表,不是指数据库中的表,而是一种数据类型,类似于map,用k-v的方式实现,从理论上来讲,
除了nil, 其他字符都可以作为k值(索引值)
格式
类似于hash
TableName=
k=v,
类似于数组 -- 下标从1开始
TableName=
x,
y,
z
可以用hash 格式和array 格式 混搭
for 循环遍历
for k,v in parirs(TableNmae) do
print(k,v)
end
C++中的pairs是对组
循环嵌套
for k,v in paris(info3) do
print(k,"==",v)
if(type(v)=="table") then
for k2,v2 in pairs(v) do
print("\\t",k2,"==",v2)
end
end
end
]]--
table中类似哈希 k-v 表示方式:
--哈希表示方式
local info1=
id=123,
name="yyw",
grade=60,
sex="male"
for k,v in pairs(info1) do
print(k,v)
end
-- local id
-- local name
-- local grade
-- local sex
-- local info2=
-- [id]=123,
-- [name]="yyw",
-- [grade]=60,
-- [sex]="male"
--
-- for k,v in pairs(info2) do
-- print(k,v)
-- end
print("\\n")
print(info1.id)
print(info1.name)
print(info1["sex"])
print("\\n")
--增加字段
info1.age=123
info1["country"]="china"
info1["province"]="shanghai"
for k,v in pairs(info1) do
print(k,v)
end
--删除字段
info1["sex"]=nil
info1.age=nil
print("\\n")
for k,v in pairs(info1) do
print(k,v)
end
--修改字段
info1["name"]="yywnb"
info1.id=456
print("\\n")
for k,v in pairs(info1) do
print(k,v)
end
输出结果:
sex male
grade 60
id 123
name yyw
123
yyw
male
province shanghai
id 123
name yyw
sex male
country china
grade 60
age 123
province shanghai
id 123
name yyw
country china
grade 60
province shanghai
id 456
name yywnb
country china
grade 60
table中类似数组表示方式:
--数组表示方式,并且lua中数组下标是从1开始的
local info2=
"yyw",
123,
true
print("\\n")
for k,v in pairs(info2) do
print(k,v)
end
--修改字段
info2[2]=234
info2[1]="yywnb"
print("\\n")
for k,v in pairs(info2) do
print(k,v)
end
--增加字段
info2[100]="contry"
info2[50]="province"
print("\\n")
for k,v in pairs(info2) do
print(k,v)
end
--删除字段
info2[1]=nil
print("\\n")
for k,v in pairs(info2) do
print(k,v)
end
输出结果:
1 yyw
2 123
3 true
1 yywnb
2 234
3 true
1 yywnb
2 234
3 true
100 contry
50 province
2 234
3 true
100 contry
50 province
PS D:\\lua代码>
hash 格式和array 格式 混搭:
--[[
基本数据类型
Lua中有8中数据类型:nil boolean number string function table userdata thread
table表,不是指数据库中的表,而是一种数据类型,类似于map,用k-v的方式实现,从理论上来讲,
除了nil, 其他字符都可以作为k值(索引值)
格式
类似于hash
TableName=
k=v,
类似于数组 -- 下标从1开始
TableName=
x,
y,
z
可以用hash 格式和array 格式 混搭
for 循环遍历
for k,v in parirs(TableNmae) do
print(k,v)
end
C++中的pairs是对组
循环嵌套
for k,v in paris(info3) do
print(k,"==",v)
if(type(v)=="table") then
for k2,v2 in pairs(v) do
print("\\t",k2,"==",v2)
end
end
end
]]--
--哈希表示方式
local info1=
id=123,
name="yyw",
grade=60,
sex="male"
for k,v in pairs(info1) do
print(k,v)
end
-- local id
-- local name
-- local grade
-- local sex
-- local info2=
-- [id]=123,
-- [name]="yyw",
-- [grade]=60,
-- [sex]="male"
--
-- for k,v in pairs(info2) do
-- print(k,v)
-- end
print("\\n")
print(info1.id)
print(info1.name)
print(info1["sex"])
print("\\n")
--增加字段
info1.age=123
info1["country"]="china"
info1["province"]="shanghai"
for k,v in pairs(info1) do
print(k,v)
end
--删除字段
info1["sex"]=nil
info1.age=nil
print("\\n")
for k,v in pairs(info1) do
print(k,v)
end
--修改字段
info1["name"]="yywnb"
info1.id=456
print("\\n")
for k,v in pairs(info1) do
print(k,v)
end
print("\\n")
--数组表示方式,并且lua中数组下标是从1开始的
local info2=
"yyw",
123,
true
print("\\n")
for k,v in pairs(info2) do
print(k,v)
end
--修改字段
info2[2]=234
info2[1]="yywnb"
print("\\n")
for k,v in pairs(info2) do
print(k,v)
end
--增加字段
info2[100]="contry"
info2[50]="province"
print("\\n")
for k,v in pairs(info2) do
print(k,v)
end
--删除字段
info2[1]=nil
print("\\n")
for k,v in pairs(info2) do
print(k,v)
end
print("\\n")
print("\\n")
local info3 =
name = "tom",
age = 23,
sex = "woman",
100,
"abc",
"xyz", "def", son1_k_1 = "son1-key-1" ,
son2 =
son2_k_1 = "son2-key-1",
name = "son2", false,
"abc-son2", 123456
,
country = "china",
100000
for k,v in pairs(info3) do
print(k,"==",v)
if(type(v)=="table") then
for k2,v2 in pairs(v) do
print("\\t",k2,"==",v2)
end
end
end
print("\\n")
print("\\n")
--修改字段
info3[3][2]="DEF"
info3[3]["son1_k_1"]="SON1-KEY-1"
info3["son2"][1]=true
info3["son2"][2]="ABC-SON2"
for k,v in pairs(info3) do
print(k,"==",v)
if(type(v)=="table") then
for k2,v2 in pairs(v) do
print("\\t",k2,"==",v2)
end
end
end
print("\\n")
--删除字段
info3[3]=nil
info3[4]=nil
for k,v in pairs(info3) do
print(k,"==",v)
if(type(v)=="table") then
for k2,v2 in pairs(v) do
print("\\t",k2,"==",v2)
end
end
end
print("\\n")
--增加字段
info3[5]=100000
info3["province"]="shanghai"
info3["son2"][4]="lua"
for k,v in pairs(info3) do
print(k,"==",v)
if(type(v)=="table") then
for k2,v2 in pairs(v) do
print("\\t",k2,"==",v2)
end
end
end
输出结果:
1 == 100
2 == abc
3 == table: 000002591D9262A0
1 == xyz
2 == def
son1_k_1 == son1-key-1
4 == 100000
sex == woman
country == china
son2 == table: 000002591D926EA0
1 == false
2 == abc-son2
3 == 123456
name == son2
son2_k_1 == son2-key-1
name == tom
age == 23
1 == 100
2 == abc
3 == table: 000002591D9262A0
1 == xyz
2 == DEF
son1_k_1 == SON1-KEY-1
4 == 100000
sex == woman
country == china
son2 == table: 000002591D926EA0
1 == true
2 == ABC-SON2
3 == 123456
name == son2
son2_k_1 == son2-key-1
name == tom
age == 23
1 == 100
2 == abc
sex == woman
country == china
son2 == table: 000002591D926EA0
1 == true
2 == ABC-SON2
3 == 123456
name == son2
son2_k_1 == son2-key-1
name == tom
age == 23
1 == 100
2 == abc
son2 == table: 000002591D926EA0
1 == true
2 == ABC-SON2
3 == 123456
4 == lua
name == son2
son2_k_1 == son2-key-1
sex == woman
province == shanghai
country == china
5 == 100000
name == tom
age == 23
PS D:\\lua代码>
7、基本运算符(一)
--[[
赋值=
lua中变量时弱类型,就是说明声明变量时候不需要类型,其类型取决于所赋的值,
并且,同一个变量,可以随时切换成不同的数据类型
多重赋值
a,b=b,a 交换,类似c,c++中的swap
算符运算符
加+、减-、乘*,除/、取模%,指数(次方)^
关系运算符
等于==,不等于~=,大于>,小于<,大于或等于>=,小于或等于<=,
关系运算符的运算结果只能是true 或者false,且只能在相同类型的数据间运算(运算时不会做隐式类型转换)
对于对象型的数据(function,userdata,table),比较运算的知识引用,就是比较对象的地址
]]--
local a=1
local b=2
local c=a
print(a,b,c)
c="string"
print(c)
c=true
print(c)
local aa,bb,cc,dd=1,"abc",true
print(aa,bb,cc,dd)
aa,bb,cc=1,"true",["aa"]=1,["bb"]=1
print(aa,bb,cc)
tab=
[aa]=1,
[bb]=2
print(tab.aa,tab.bb)
tab=
["aa"]=1,
["bb"]=2
print(tab.aa,tab.bb)
local aaa,bbb=1,"string"
print(aaa,bbb)
local aaa,bbb=bbb,aaa
print(aaa,bbb)
print(10%3)
print(10%3.0)
print(10/3)
print(10/3.0)
print(2^10)
print(1==1)
print(1=="1")
print(1~="1")
local aaaa='1'
--print(1>="1") --err 语法错误
print(1+'1') --做了隐式类型转换
print(1+aaaa)
local tab3=
["ip"]="172.164",
["port"]="3306"
local tab2=
["name"]="lua"
print(tab3==tab2)
print(tab3.ip==tab2.name)
local tab4=tab3
print(tab4==tab3)
print(tab4==tab2)
print(tab3.ip==tab2.name)
输出结果:
1 2 1
string
true
1 abc true nil
1 true table: 000002724B31A430
nil nil
1 2
1 string
string 1
1
1.0
3.3333333333333
3.3333333333333
1024.0
true
false
true
2
2
false
false
true
false
false
PS D:\\lua代码>
8、基本运算符(二)
--[[
逻辑运算符
逻辑与 and、或 or、非 not
&& || !
在lua中、逻辑运算与其他语言不是同一个意思、其运算结果返回值是参与运算的变量之一(not除外),
not只返回true、false,在其他语言的逻辑运算、返回值是0或1(flase 或true),意思是返回一个bool值
在lua中,只有nil(NULL,null)和false为假,其他都为真、包括空串或者0值
对于and 和 or,实行短路运算(又称短路规则,短路求值,就是说,当前面的表达式可以返回时,就直接返回,不管后面的表达式)
]]--
--[[
逻辑运算符
逻辑与 and、或 or、非 not
&& || !
在lua中、逻辑运算与其他语言不是同一个意思、其运算结果返回值是参与运算的变量之一(not除外),
not只返回true、false,在其他语言的逻辑运算、返回值是0或1(flase 或true),意思是返回一个bool值
在lua中,只有nil(NULL,null)和false为假,其他都为真、包括空串或者0值
对于and 和 or,实行短路运算(又称短路规则,短路求值,就是说,当前面的表达式可以返回时,就直接返回,不管后面的表达式)
]]--
local a,b=1,2
print(a and b) --如果a为真,则返回b
a=nil
print(a and b) --如果a为假,则返回a
print("\\n")
local c,d=1,false
print( c and d) --如果c为真,则返回d
c=nil
print(c and d) --如果c为假,则返回c
print("\\n")
local e,f=1,false
print(e or f) --如果e为真,则返回e
e=nil
print(e or f) --如果e为假,则返回f
print("\\n")
local g,h=1,2
--print(g not h) --错误写法
print(not g) --如果e为真,则返回假
print(not h) --如果h为真,则返回假
local i= false
print(not i) --如果i为假,则返回真
print<以上是关于lua学习笔记的主要内容,如果未能解决你的问题,请参考以下文章