lua语言学习笔记

来源:互联网 发布:火狐javascript设置 编辑:程序博客网 时间:2024/06/09 18:40
1.boolean: 除了false和nil,其它都为true
2.number: 2e+1 2乘10的一次方 2e-1 类似
3.string: " "或' '都可以 多行字符串使用[[ ]]
           字符串组拼 a="abc".."edf" 不能使用'+';
           #"asdf"  取字符串长度,中文占2位
4.table:   tab1={} 空表
           tab2={key1=100,key2="value2"}  tab2.key1||tab2["key1"]
           tab3={"apple","pear","orange"}  tab3[1] 注意table存数组索引从1开始
  遍历 for key,val in pairs(table) do
           --操作--
       end
  实际上table的用法非常自由,在数组中也可以直接添加字符串索引或者不连贯的数字索引都没有问题
  对table数据执行"=nil"操作会直接从数组中删除而不是置为null
  #table 可以获得table的最大索引


5.默认全局变量 加local为局部变量
  do ... end 分割代码块其中的局部变量会在end后被销毁


6.lua中可以多变量同时赋值
  a,b=10,20  相当于a=10,b=20
  a,b=b,a    a=20,b=10 lua会先计算右面的值然后赋给左面
  a,b=10,20,30 a=10,b=20 lua中多出来的赋值会被忽略
  a,b,c=10,20 a=10,b=20,c=nil
  
  function test()
   return 10,20
  end
  a,b=test()
  结果 a=10,b=20
  lua 在多返回值的情况下会忽略多于用于接收的变量的返回值


7.lua中的循环
  while(condition) do
      statements
  end


8.lua中函数的可变参数
  function test(...)
      return arg
  end
  arg是一个带入参数的表,最后一位为参数的个数
  可以使用 local arg={...} 来获得一个所有参数的表(不带参数个数)


9.运算符 +-*/^%  ==  -=  >= <= > < and not or
  
10.iterator迭代器
  array={"q","w","e","r"}
  array[2]=nil
  for k,v in pairs(array) do
    print(k,v)
  end
  for k,v in ipairs(array) do
    print(k,v)
  end
  输出结果 :1 q
             3 e
             4 r
             1 q
  pairs与ipairs的区别:pairs会遍历集合中所有的元素,ipairs只会按索引遍历,一旦遍历中有索引元素为nil,则中止迭代,两者都是提供的迭代器。
  自定义迭代器
  function square(count,controller)
   if controller<count then
   controller=controller+1
   return controller,controller*controller
   else
   return nil
   end
   end
for k,v in square,5,0 do
   print(k,v)
   end
1 1
2 4
3 9
4 16
5 25


11 table的操作
   连接:table.concat(mytable,",")
   插入:table.insert(mytable,"t")
   移除:table.remove(mytable,2)
   排序:table.sort(mytable)


12.lua中的模块与包
   lua中的模块类似与面向对象中的类,但是它是以table表实现的,新建一个lua文件
   module={}
   module.name="module"
   function module.func1()
     print("这时module的方法func1")
   end
   return module
   最后返回一个table表,表中包含了属性和方法(不包括local部分)
   调用的时候需引入 request "模块名"
   require "module"  
   module.func1()
   print(module.name)
   还可以把引入的table 赋给一个变量
   local m = require "module"


13.lua中的元表metatable】
   元表可以定义一些对table的一些额外操作,如表的相加,查找不存在的表元素等
   给一个表设置元表 setmetatable(table,metatable) 返回表
   获得一个表的元表 getmetatable(table)           返回元表
   
   1)__index :取不存在的键的时候会调用元表中的__index
             __index可以是函数,也可以是表
   eg. mymetatable={
       __index=function (table,key)
       print("调用的"..key.."不存在")
       end
       }
       mytable= setmetatable({"q","w","e","r"},mymetatable)
       print(mytable[5])
   输出:调用的5不存在
         nil
   table 和 key 是预定义的值,前者是表,后者是调用的不存在index
   eg. newtable={}
       newtable[7]="u"
       newtable[8]="i"
       newtable[9]="o"
       mymetatable={
       __index=newtable
       }
       mytable= setmetatable({"q","w","e","r"},mymetatable)
       print(mytable[8])
   输出:i
   
   2)__newindex: 向表中添加新的键值对的时候调用,可以为表可以为函数
   eg.mymetatable={
      __newindex=function (table,key,value)
      print("向表中添加了索引为"..key.."值为"..value)
      rawset(table,key,value)
      end
      }
      mytable= setmetatable({"q","w","e","r"},mymetatable)
      mytable[8]="i"
      print(mytable[8])
   输出:向表中添加了索引为8值为i
         i
   在__newindex函数中向表中添加新的键值对要调用 rawset(table,key,value) 不能直接添加(死循环)
   
   __newindex设为表的时候,会把添加的键值对添加到设的表中而不是原来的表中


   3)__add:对两个表相加的时候调用,为函数
   mymetatable={
   __add=function (tab,newtab)
   for k,v in pairs(newtab) do
   table.insert(tab,v)
   end
   end
   }
   mytable= setmetatable({"q","w","e","r"},mymetatable)
   newtable={"t","y","u"}
   t=mytable+newtable
   print(table.concat(mytable,","))
   print(table.concat(newtable,","))
   
   输出结果:q,w,e,r,t,y,u
             t,y,u
  其余运算法同理
  __add 对应的运算符 '+'.
  __sub 对应的运算符 '-'.
  __mul 对应的运算符 '*'.
  __div 对应的运算符 '/'.
  __mod 对应的运算符 '%'.
  __unm 对应的运算符 '-'.
  __concat 对应的运算符 '..'.
  __eq 对应的运算符 '=='.
  __lt 对应的运算符 '<'.
  __le 对应的运算符 '<='.  
  
  4)__call :在调用table中的一个值的时候调用,即把表当方法用
  eg. mymetatable={
      __call=function (tab,arg1,arg2,arg3)
      print(arg1,arg2,arg3)
      return arg1
      end
      }
      mytable= setmetatable({"q","w","e","r"},mymetatable)
      print(mytable(12,354,54))
  输出结果:12 354 54
            12
  5)__tostring:直接输出或者把table当字符串使用的时候调用
     mymetatable={
     __tostring=function (mytable)
     local str=""
     for k,v in pairs(mytable) do
     str=str..v
end
     return str
     end
     }
     mytable= setmetatable({"q","w","e","r"},mymetatable)
     print(mytable)  
   输出结果:qwer
   
14.lua中的协同函数
   创建 coroutine.create(方法名或匿名方法) 返回一个协程函数
   暂停 coroutine.yield(可带返回值) 返回值是从resume中传递回的参数
   重启或开始 coroutine.resume(协程函数名,向协程传递的参数(可以传递给yield的返回值)) 返回值可以接收 第一个值为bool是否启动成功,后面为函数的返回值
   获得协同函数状态 coroutine.status(协程函数名)返回值包括 dead,suspend,running
   获得正在运行的协程 coroutine.running()
   function multi(a,b)
   print(a)
   coroutine.yield(a,b)
   print(b)
   return a*b
   end
   co1=coroutine.create(multi)
   ref1,ref2,ref3=coroutine.resume(co1,50,50)
   ref1,ref2=coroutine.resume(co1)
   print(ref1,ref2)
   输出结果:
   50
   true  50 50
   50
   true  2500
   
15.I/O
   简单模式
   打开文件 io.open(文件路径或当前文件目录的文件名,模式)
   r 以只读方式打开文件,该文件必须存在。
   w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
   a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)
   r+ 以可读写方式打开文件,该文件必须存在。写入会清空之前的信息
   w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
   a+ 与a类似,但此文件可读可写
   b 二进制模式,如果文件是二进制文件,可以加上b
   + 号表示对文件既可以读也可以写
eg.file=io.open("data.txt",r)
   io.input(file)
   print(io.read())
   io.close()
   
   file=io.open("data.txt","r+")
   io.output(file)
   io.write("一二三四")
   io.write("五六七八")
   
   read()中可以带的参数
   "*n" 读取一个数字并返回它。例:file.read("*n")
   "*a" 从当前位置读取整个文件。例:file.read("*a")
   "*l"(默认) 读取下一行,在文件尾 (EOF) 处返回 nil。例:file.read("*l")
   number 返回一个指定字符个数的字符串,或在 EOF 时返回 nil。例:file.read(5)
   
   完全模式
  打开文件与简单模式相同
  使用句柄 file=io.open("data.txt","a")
  print(file:read())
  file.write()
  file:seek(optional whence, optional offset): 设置和获取当前文件位置,成功则返回最终的文件位置(按字节),失败则返回nil加错误信息。参数 whence 值可以是:
  "set": 从文件头开始
  "cur": 从当前位置开始[默认]
  "end": 从文件尾开始
  offset:默认为0
  file.flush() 缓冲区全部写入
  file.lines(optional file name) 按行迭代获取文件内容
  
15.lua中的面向对象编程
  1)使用table来模拟对象
  person={name="kzg",age="22"}
  function person:eat()
  print(person.name.."在吃饭")
  end
  person:eat()
  2)使用table表模拟面向对象,对象中的函数尽量使用":"而不是"."这样可以在函数中使用"self"保留字来获得自身
  
  模拟对象的创建(构造函数):使用元表的__index实现以初始表为原型来创建新表,以此模拟创建类的对象
  Person={name="kzg",age="22"}
  function Person:eat()
  print(self.name.."在吃饭")
  end
  function Person:new()
     local t={}
setmetatable(t,{ __index=self })
return t
  end


  person1=Person:new()
  person2=Person:new()
  print(person1.name)
  person1:eat()
  person2.name="asd"
  person2:eat()
  输出结果:kzg
            kzg在吃饭
            asd在吃饭

  3)与C#的创建对象不同,还可以在构造函数里直接向表里添加新的成员
    function Person:new(o)
     local t=o or {}
setmetatable(t,{ __index=self })
return t
    end
person1=Person:new({height="176"})
print(person1.height)
输出结果:176

  4)使用lua实现继承的模拟
    使用new()创建子表
    Student=Person:new()
添加一些父类没有的属性
    Student.grade=60
创建子表的实例
stu1=Student.new()
stu1:eat()
    print(stu1.grade)
    输出结果:kzg在吃饭
              60
可以看出已经模拟了继承,当调用子表中不存在的数据会往上搜索(其实就是查找元表)
   
原创粉丝点击