lua語言學習筆記

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
可以看出已經模擬了繼承,當調用子表中不存在的數據會往上搜索(其實就是查找元表)
   
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章