Lua编程总结

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



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值