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

最后输出的结果是

lua语言read LUA语言编程_c#

将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既可以调用父类的方法,变量,也可以添加新的