Lua语法总结

1.字符串拼接用…表示,例如str1…str2,不能用加号。
如果在字符串之间用算术符的话,会直接转成数字运算,例:“2”+“3” ,结果就是5

2.table可以用来做数组,也可以用来做字典,table是不固定大小的。
数组形式:tab1={“one”,“two”,“three”};
字典形式:tab2={key1=“one”,key2=“two”}
删除并不影响其他的其他的数据,只会让自身的数据消失
tab2.kay1=nil
本来有的可以直接覆盖进行修改
tab2.key1=1
本来没有的可以直接添加,但是tab2必须存在
tab2.kay3=1
tab2[“kay3”]=1
遍历
for kay.val in pairs(table) do
print(tab2.kay)
end

3.Lua 的使用是不需要类型的
4.end 表示的是语句的结束,类似于}
5.函数
function test(n)
if n==1 then
return n
end
end
test2=test
函数能赋值,也能作为参数传递,类似于c#的委托和事件
if后面要带then

6.匿名函数:只需要使用一次,少量代码
testFun(tab,
function(k,v)
print(k…"-"…v)
end
)

7.nil 的布尔值默认为false
8.userdata(自定义类型),可以用来存放c/c++的数据,让lua使用
9.lua定义默认都为全局变量,lua是根据数据来改变类型的,可以用local 来定义局部变量,尽可能地使用局部变量
10.如果函数没有被调用,里面的变量也不会赋值,就算是全局变量
11.局部和全局变量重名,优先访问局部变量,do end是一段代码段
do
local a=10
print(a,b)
end
12.多个变量同时赋值
a,b,c=10,20,“hello”
直接交换,lua会先计算右边的值,再进行赋值
a,b=b,a
值的数量多于变量,多出来的会被忽略
变量的数量多于值,多出来的会被赋值nil
13.多值return
function test()
return 40,50
end
a,b=test()

14.一些不同的运算符
~=表示不等于
and or not 表示与或非
#取尾部索引,如果有键值对的话
…表示可变参数,arg会保存可变索引的值,但是尾部有存储个数的值,所以#arg的话取到的只是个数,不是长度

15.函数也尽量用小写,因为lua里面很多大写保留字

16.string.upper(),string.lower()用来转换大小写。
string.reverse()用来翻转,string.gsub(str,“里面的字符”,替换的数据)
string.char[arg]用来把数据转换char类型
string.byte[arg]用来把字符转换成number类型
string.match() 模式匹配,正则表达式

17.lua索引默认都是从1开始的,但是索引却可以是任何值(包括负数和0)
18.引用类型的赋值都相当于把指针指到了同一片区域,相当于浅拷贝,一个改变则会影响到另一个,但是一个置nil,并不会影响到另一个的指向。
19.二维数组
table={{},{},{}}
table[1]={1,2,3}
table[2]={4,5,6}
table[3]={7,8,9}
for k,v in pairs(table) do
for k,v in pairs(table[k]) do
print(k,v)
end
end
20.table的一些函数
table.concat(mytable,“分隔符”) 把table里面的东西拼接起来,但是只能是一维的
table.insert(mytable,插入位置,插入值)默认为插入末尾
table.remove(mytable,移除位置)默认为移除末尾
这两个函数都会保持table的连续性
table.sort()排序方法

21.变量名不要和关键字重名,尽管有时候不报错,但是很多隐患

数值for循环
step =1
n=3
for i=1,n,step do
print(i)
end
泛型for循环
for k,v in pairs(tab) do
print(k,v)
end
pairs是一个迭代器,类似于iterator。
ipairs也是一个迭代器,但是只能迭代到连续的最后一个,而pairs则是全部。

23.module模块
module={}

module.tab={{},{},{}}
module.tab[1]={1,2,3}
module.tab[2]={4,5,6}
module.tab[3]={7,8,9}

function module.fun1()
for k,v in pairs(module.tab) do
print(k,v)
end
end

function module.fun2()
print(“fun2”)
end
return module
必须return 了才可以在外部require
通过require “文件名” 引用模块

24.元表:metatable是作为表的一个拓展开发,它实质上也是一个表
metatable={__metatable=“lock”}
table={“c#”,“Java”,“c++”,“c”};
table=setmetatable(table,metatable)
print(getmetatable(table))
print(metatable)

用setmetatable来设置一个表的元表,然后返回的表的本身。
用getmetatable来获取一个表的元表,但是如果元表中,与__metatable这个键的话,则会返回其对应的键值,如事例中的lock
__metatable这个键实现了对元表的保护,禁止与外界访问或修改元表中的成员

25.元方法
__index这个键扩充不存在元素的访问
__index可以等于一个函数,一旦访问到不存在的元素时就会调用这个函数
metatable={__index=function (tab,key)
return “未定义”
end
}
table={“c#”,“Java”,“c++”,“c”};
table=setmetatable(table,metatable)
print(table[5],table[6])//输出为 未定义 未定义
也可以等于一个表,然后外部表没有的元素,才会访问这个元表中的元素,如果存在的并不会被元表取代。

__newindex这个键当我们添加新的数据的时候会起作用
newTable={}

metatable={__newindex=newTable}
table={“c#”,“Java”,“c++”,“c”};
table=setmetatable(table,metatable)

table[5]=“lua”
print(newTable[5])//输出为lua
如果__newindex等于一个表的话,我们在旧表新添加的元素都会存在这个新表当中,而旧表是不会发生变化的。

当然__newindex也可以赋值为一个函数,例如
metatable={__newindex=function (tab,kay,value)
print(“添加的新元素为”)
rawset(tab,kay,value)
end
}

table={“c#”,“Java”,“c++”,“c”};
table=setmetatable(table,metatable)

table[5]=“lua”
print(table[5])
这个值得注意的是函数是传入三个值的,value表示要赋予的值,即当我们添加元素的时候会调用这个函数,但是如果没有rawset(tab,kay,value) 这个函数的话,这个新元素是添加不进去的,相当于__newindex让我们重写了添加元素的方法。

__add这个键用来扩充加法法则,但对于原有的加法是不受影响的
newTable={“lua”,“PHP”}
table={“c#”,“Java”,“c++”,“c”};
metatable={__add=function(tab,newTable)
local len1=#tab+1;
local len2=#newTable
local j=1
for i=len1,len1+len2,1 do
if(j<=len2)then
tab[i]=newTable[j]
j=j+1
else
break
end
end
return tab
end

table=setmetatable(table,metatable)
table=table+newTable
newTable=newTable+table
for k,v in pairs(table)do
print(k,v)
end
//这两个table是一样的,证明了只要有一个table的元表的加法,就可以和其他table进行加法运算
for k,v in pairs(newTable)do
print(k,v)
end

__call这个键能把原来的表扩展成一个函数来使用,可能后面我们会用到它来实现更多的功能
table={“c#”,“Java”,“c++”,“c”};
metatable={__call=function(tab,value1,value2)
print(value1,value2)
end
}

table=setmetatable(table,metatable)
table(1,2)//输出1,2

26.协同程序:
coroutine.creat()用来创建协同程序,而coroutine,resume()用来启动协同程序
coroutine.yield()用来暂停协同程序,coroutine.resume()用来重新启动,重新启动的时候不用传参数。

co=coroutine.create(
function(a,b)
print(a+b)
coroutine.yield()
print(a-b)
end
)
coroutine.resume(co,20,30)
print(“我是间隔”)
coroutine.resume(co)

coroutine.wrap()也可以用来创建,而且不需要resume来启动
co2=coroutine.wrap(
function(a,b)
print(a+b)
end
)
co2(20,30)
但是要注意的是如果把yield放到wrap里面的话,就不能用resume来重新启动了,暂时没找到解决方法。

coroutine.status(协调程序名),该函数会返回协同程序当前的状态,还没启动时为suspended,启动后为running,结束为dead,当协程dead之后就不能用resume来重新启动了
coroutine.running()在协程里面调用,可以返回协程号。
coroutine.yield(返回的参数···可以为多个)
res1,res2,res3=coroutine.resume(co…)–yield的参数会在这里接收,但是第一个返回的参数是调用是否成功的bool值,后面的参数才是和yield对应的。
而第二次重新启动的时候接收的参数就是return返回的参数,相同的是第一个返回的参数还是bool值

特别注意的是一个协同程序中是允许有多个yield的

27.lua面向对象的封装和继承
Person={name=“xiaoming”,age=“99”}–定义一个人的表
function Person:new()
local t={}
setmetatable(t,{__index=self})–[[t为原来的表,比如说下面的Person2和Student,self就是Person表,因为用了冒号,所以可以用self来表示自身,不用传参数。也就是说如果没定义的元素访问就会访问到Person表中的元素,当然如果原表有了,就不会访问到了]]–
return t
end

Person2=Person:new()
Person2.name=“xiaohong”–这时访问到的就是小红,然后age就是默认的99
Person2.weight=“100”–我们也可以添加新的元素

–多重继承
Student=Person:new()–Student是人,所以继承了Person类
Student.grade=1–我们可以定义一些Student自己的属性
Student.age=2
Student1=Student:new()–然后让Student1继承至Student表,但是实质上用的是Person的new函数
print(Student1.name,Student1.age,Student1.grade)

Person={name=“xiaoming”,age=“99”}
function Person:new(o)–当然我们还可以从这里传递进参数
local t=o or {}–如果没有参数的话,我们就生成空表,有参数的话就直接使用这个表了
–setmetatable(t,{__index=self})
setmetatable(t,self)–另外一种写法
self.__index=self
return t
end

kay={grade=1,age=2}

Student=Person:new(kay)–把kay表传递进去

Student1=Student:new()
print(Student1.name,Student1.age,Student1.grade)

28.文件流操作分为简单模式和完全模式
简单模式:
file=io.open(“data.txt”,‘r’)–以只读的模式打开,这些读取模式可以参照c语言的读取模式
io.input(file)
str =io.read()–读取一行
str2 =io.read()
io.close(file)–打开文件后一定要记得关闭,不然会出现一些未知的错误
print(str,str2)
值得注意的是:只读模式(r)只能在文件存在的时候才能打开,而写模式(w)如果文件不存在,就会自动生成一个新的文件,而写入时会把原有的文件清空。追写模式(a)则可以在后面直接在文件尾部追写文件。而如果在后面添加加号的话(r+,w+,a+),都会变成可读可写,而r+也一定要文件存在才可以打开。
io.read("*l")–默认为读取一行
io.read("*a")–读取整个文件
io.read(number)–读取几个字符
完全模式:
file:read()
file:write()
完全模式是不需要使用io开头的函数的,也就不需要input了,通过flie:来调用函数。
file=io.open(“data.txt”,‘r’)
str =file:read()–读取一行
file:close(file)

29.垃圾回收机制
lua的垃圾回收是自动的。
它实现了一个增量标记-扫描收集器,它里面有两个数值,一个为垃圾收集器间歇率(垃圾回收的间隔)和一个垃圾收集器步进倍率(控制着垃圾收集器的运行速度)。
但是我们也可以通过函数来直接调用里面的方法,例如:
collectgarbage(“collect”)–释放可释放内存,但是释放后也不可能是0
collectgarbage(“count”)–显示占用内存

30.lua的错误
运行错误关键字:expected
语法错误关键字:syntax error

猜你喜欢

转载自blog.csdn.net/qq842447820/article/details/82876309