Lua是一个轻量的脚本语言,不需要编译就可以运行
在使用lua编译器时按F5无法执行脚本,这是因为文件没有保存,先保存才能执行文件
注释语句用--来表示,多行注释用--[[ 来开头用--]]来结尾,每一条语句后面的;可加可不加
默认情况下,变量总认为是全局的,不像c#中 int b=10; 在lua中直接b=10;即可,c#输出空为null,在lua中输出为nil
如果要删除一个变量,把它设置为空即可,b=nil;当然如果一个表设置为nil就会把这个表也置空了,在boolean类型中nil默认为false,其他为true
type的用法:
返回的是该数据的类型
print(type("hello")) -- 输出为string
print(type(10)) --输出为number
print(type(type)) --输出为function
print(type(x)) --输出为nil
+和..和#的运算:
print("2"+6) -- 这样相加会把字符串的数字也转成number类型进行相加
print('123'..'345') -- 这里..的用处是将两个字符串进行组拼输出为123345,必须是字符串,数字是不能组拼的,同时字符串用'或者"都行
print(#str) --这里#的用法是计算字符串的长度输出
lua中的表结构:
可以理解为字典的形式
tab1={key1=100,key2="value"}
print(tab1.key1) -- 这里输出的是100,记住输出的是value而不是key的值
表的另一种形式:
tab1={"green","red","orange"}
print(tab1[2]) --输出的是red
当然,要想输出表,这样做
tab1={'red','green','orange'}
for key,value in pairs(tab1) do
print(key..":"..value)
end
输出为
1:red
2:green
3:orange
注意表的索引是从1开始的不是0开始
函数function:
函数开头返回的类型不指定,同时传参类型不指定,有if或者循环或者函数结束的时候要用end来表示结束
function fact(n)
if n==1 then
return n
else return n*fact(n-1)
end
end
当然函数也可以当做参数来传递,如果该函数被当做参数传入且只用一次,可以用匿名函数,函数名称不用定义,直接用function来代替,比如
myprint=function (a)
print("函数"..a)
end
这里把一个匿名函数赋给了myprint,我们使用函数的时候可以myprint(100),那么会执行函数为 函数100
全局变量和局部变量:
局部变量前面加上local表示局部变量
function teset()
a=10
local b=20
end
teset()
print(a)
print(b)
在此函数中a=10是全局变量,所以函数结束时候仍然可以访问,而局部变量不可以,因此输出为10和nil
多变量赋值:
a,b=10,20 --把10,20赋给a,b
a,b=b,a --交换a,b的值,当然如果把两个数给一个变量,变量接受最前面的
a=10,20 --a为10
for循环:
for i=0,10,2 do
print(i)
end
这里意思是让i=0;i<=10;i=i+2,注意这里是i<=10而不是i<10
repeat until循环(类似于do while):
格式:
repeat
循环体
until (condition)
可变参数...
在函数的参数中如果设为...那么表示函数的参数个数是不确定的,此时,用arg这个表来表示参数其中k表示第几个参数,v表示参数的值
function test(...)
for k,v in pairs(arg) do
print(v)
end
end
这个函数会打印出参数的值,如果要计算参数的个数,#arg即可
注意在lua中不等于是这样写的if 1 ~= 2,还要注意的是lua中大小写是不一样的,是区分的
逻辑表达式 and or not(相当于c#中的&& || 和!)
字符串的操作
str="my name is"
str1=string.find(str,"name",10) -- 这里是查找str字符串中name的位置,如果没有10,str1为4,有10,表示从第10个索引后查找,输出为nil
字符串反转
str1=string.reverse(str)
字符串格式化,用%d表示数字,%s表示字符串
str1=string.format("你的成绩为%d",20)
print(str1)
表的操作
表的连接
mytable={"c","c++","c#"}
table.concat(mytable) --这里输出的应该是cc++c#
table.concat(mytable,",") --这里输出的应该是c,c++,c#
表的插入
table.insert(mytable,"aa") --在mytable表的末尾插入aa的数据
table.insert(mytable,2,"aa") --在mytable表的2号索引插入aa的数据
表元素的删除
table.remove(mytable,2) --删除2号元素
表元素的排序
table.sort(mytable)
lua引入模块
引入其他文件在文件的开头加上
require "文件名"
注意:如果定义一个表,那么这里modeal.func表示modeal表中的一个匿名函数
modeal={}
modeal.func=function ()
print("aa")
end
元表
定义:当两个表的元素进行操作时使用元表
mytable={"c","c#","c++"}
mymetatable={} --先设置两个表
mytable=setmetatable(mytable,mymetatable) --调用setmetatable函数来将普通表放到第一个,元表放到第二个,用普通表来接收,这是设置元表的操作,得到元表的操作时这样
getmetatable(mytable)
__index元方法:当查询普通表的key值不存在时会调用这里的index的具体方法
格式:
元表名 ={
__index = function (普通表名,key)
具体操作
end
}
__newindex元方法:当查询普通表的key值不存在时或添加新的键值对时起作用
mymetatable={
__newindex=function(普通表名,key,value)
--具体操作
end
}
情况2
mymetatable={
__newindex=mynewtable
}
如果传递了一个新的table给了newindex那么对普通表插入新的键值对会自动放到元表中,不会放到普通表中
为表添加操作符(两个表元素进行加减乘除)
mytable={"red","green",'"orange"} --步骤1,定义一个普通表
mymetatable={ --定义相加的规则永远是在元表中进行 步骤2,定义一个元表并且设置好处理函数
__add=function(mytable,mynewtable) --注意这里要传入两个相加的表名
--进行两个表元素的混合,首先要找到第一个表的最大索引
a=#mytable
--接着遍历第二个表的元素依次放到第一个表后面
for k,v in pairs(mynewtable) do
mytable[a+k]=v
end
end
}
mytable=setmetatable(mytable,mymetatable) --步骤3 通过setmetatable进行绑定
mynewtable={"blue","puple"} --步骤4 定义一个新表
v=mytable+mynewtable --步骤5 进行两个表的操作,两个表相加必须用一个表接收
for k,v in pairs(mytable) do --最后输出
print(k,v)
end
最后输出的结果是
将mytable扩容了
注意这里+操作对应的是__add函数,如果修改-操作用__sub函数
__call元方法:
与上面类似,只不过写函数名时__call=function(mytable,arg)
然后处理函数,在调用表时,mytable(100)那么100当做arg传进去处理
__tostring元方法:修改了表的输出行为
__tostring =function(mytable)
local str="" for k,v in pairs(mytable) do
str=str..v.."," --可不是str=str+v+","
end
return str
end
最后调用print(mytable) 输出为red,green,orange
协程:在执行协程函数时可以指定某个时刻暂停,等到特定时刻继续运行该函数
定义协同函数
co=coroutine.create( --注意是()不是{ }
function (a,b) --匿名函数不起名字
print(a+b)
end
)
启动协同函数
coroutine.resume(co,4,5) --传入的两个参数对应函数的参数
第二种定义启动协同函数的方式:
co=coroutine.wrap(
function (a,b) --匿名函数不起名字
print(a+b)
end
)
启动函数
co(4,5)
协同函数挂起和继续:
co=coroutine.create(
function (a,b)
print(a+b)
coroutine.yield() --协同函数的挂起
print("结束")
end
)
coroutine.resume(co,4,5) --只运行print(a+b)
print("I am here")
coroutine.resume(co) --继续运行挂起的协同函数,那么就不需要传入参数
读取文件io
读文件:
file=io.open("text1.txt","r") --r为只读模式
print(file:read()) --读取该文本一行数据
file:close()
lua面向对象
由于不像c#有类,对象,因此要想实现面向对象通过table+function来实现
对于一个对象来说它是有变量和方法的,同样table也可以放变量和方法
对于table里面的方法重写,这样写:
mytable={}
function mytable.eat()
print("在吃饭")
end
mytable.eat()
这里注意的是表里面的函数既可以用mytable.eat()表示也可以用mytable:eat()表示,区别是如果定义函数参数是self,那么mytable.eat(mytable)
也可以mytable:eat() 这句话还是有错误的,先别记
另一种情况:
mytable={}
function mytable:eat()
print("在吃饭")
end
function mytable:new1()
t={} --这里的t最好声明为local,不然外界也可以调用
setmetatable( t,{ __index=self } ) --调用属性的时候,如果t不存在就调用index所指的表中查找,这里self指的是mytable
return t
end
mytable1=mytable:new1()
mytable1:eat() --打印出在吃饭
在这里mytable创建了new1方法,要想创建它的对象就调用该方法即可,mytable1既可以调用父类的方法,变量,也可以添加新的