Metatable讓我從心認知了Lua(相知篇)


   自從在公司和Lua第一次相遇之后,我的IT生涯從此也開啟了另一個新篇。。。

起初並沒有和Lua產生相遇時的那種電石火花般的怦然心動。。。但。。。

說實話雖然我的心沒有因此觸動但至少也不排斥。。。因為公司的需要,我就

必須去愛上她,所以大家都懂得。。。我們開始了正式的"交往"咯^_^ ^_^ ^_^

  在與Lua"交往"的這段時光里,你會發現自己已經漸漸的被Lua所吸引。。。

她雖然沒有令你一見鍾情的"容貌",但卻有着你喜歡的那種日久生情的"氣質"。。。

  廢話就不多說了、、、咱直接進入主題吧。。。細說Metatable(元表)的那點事。。。

如果你想對lua中table的結構進行變化。。。那么就用lua的元表就來幫你實現。。。請看下面詳解。。。

==>這次的博文新增了導航欄,,,方便博友們上下滾動網頁來回切換視角、也別忽視了右側的浮動目錄。。。

 

一、 __index元方法

__index元方法:用於查看表中元素是否存在,如果不存在返回結果為nil;如果存在,則由__index返回結果

  存在__index元方法:

myTable = setmetatable({key1 = "lua", key3 = "java"}, {
    __index = function(myTable, key)
        if key == "key2" then
          return "key2 is nil"
      else
          return myTable[key]
      end
    end
})

  程序運行輸出:

---------- 新建程序 ----------
lua    key2 is nil    java

輸出完成 (耗時 0 秒) - 正常終止

 

  不存在__index元方法:

myTable = {key1 = "lua", key3 = "java"}

print(myTable.key1, myTable.key2, myTable.key3)

  程序運行輸出:

---------- 新建程序 ----------
lua    nil    java

輸出完成 (耗時 0 秒) - 正常終止

 

二、__newindex元方法

__newindex元方法:用來對表進行更新。給一個表的缺少的索引賦值時,解釋器就會查找是否存在__newindex元方法,

          如果存在則調用這個函數而不進行賦值操作;不存在則進行賦值操作。(只針對表中不存在的索引有效)

  存在__newindex元方法:

myTable = {key1 = "lua", key3 = "java"}

setmetatable(myTable, {
    __newindex = function(myTable, key, value)
      print(key .. " is not exists in myTable " .. value)
    end
})

myTable.key1 = "hello"
myTable.key2 = "world"    --給key2賦值會執行__newindex函數

print(myTable.key1, myTable.key2)

  程序運行輸出:

---------- 新建程序 ----------
key2 is not exists in myTable world
hello    nil

輸出完成 (耗時 0 秒) - 正常終止

  解釋說明:  在給myTable表的key1索引賦值時,因為key1索引是myTable中已經存在的索引,

       所以只進行賦值而不調用__newindex元方法;

         在給myTable表的key2索引賦值時,因為key2索引在myTable表中不存在,解釋器就會查找

       是否存在__newindex元方法,又由於存在__newindex元方法,所以調用了__newindex元方法

       而不對key2索引進行賦值;若不存在__newindex方法,則對新索引進行賦值操作。 

 

   不存在__newindex元方法:

myTable = {key1 = "lua", key3 = "java"}

myTable.key1 = "hello"
myTable.key2 = "world"    

print(myTable.key1, myTable.key2)

  程序運行輸出:

---------- 新建程序 ----------
hello    world

輸出完成 (耗時 0 秒) - 正常終止

 

三、__add元方法

 __add元方法:用於操作表與表之間的關聯事件。當兩張表之間用到字符'+'時,解釋器就會去查找是否存在__add元方法,

        若存在__add元方法,則調用__add元方法,否則程序執行報錯。(對應的運算符:'+')

   存在__add元方法:

myTable = {10, 20, 30}
newTable = {20, 30, 40}

setmetatable(myTable, {
    __add = function(myTable, newTable)
      print("add")    --此處用來處理相關事件,可遍歷兩個對其中的元素進行累加求和並返回
      return "already add"
    end
})

print(myTable + newTable)

  程序運行輸出:

---------- 新建程序 ----------
add
already add

輸出完成 (耗時 0 秒) - 正常終止

 

四、__sub元方法

 __sub元方法:用法類似於__add元方法。(對應的運算符:'-')

myTable = {10, 20, 30}
newTable = {20, 30, 40}

setmetatable(myTable, {  
    __sub = function(myTable, newTable)  --__sub可替換__mul/__div/__mod/__unm/__concat/__eq/__lt/__le
      print("subtract")    --處理相關事件
      return "already subtract"
    end
})

print(myTable - newTable)  --此處要替換為相應的對應運算符

  程序運行輸出:

---------- 新建程序 ----------
subtract
already subtract

輸出完成 (耗時 0 秒) - 正常終止

 類似於__add和__sub元方法的還有:

  __mul元方法:對應運算符'*'

  __div元方法:對應運算符'/'

  __mod元方法:對應運算符'%'

  __pow元方法:對應運算符'^'

  __unm元方法:對應運算符'-',此處的運算符不是減號,是代表負數

  __concat元方法:對應運算符'..'

  __eq元方法:對應運算符'=='

  __lt元方法:對應運算符'<'

  __le元方法:對應運算符'<='

 

最后再拿__unm元方法舉例:

myTable = {10, 20, 30}

setmetatable(myTable, {
    __unm = function(myTable)
      print("nagative")    --處理相關事件
      return "already nagative"
    end
})

print(-myTable)

  程序運行輸出:

---------- 新建程序 ----------
nagative
already nagative

輸出完成 (耗時 0 秒) - 正常終止

 

五、__call元方法

 __call元方法:用於表變量調用一個參數時調用__call元方法。

myTable = {10, 20, 30}
num = 100

setmetatable(myTable, {
    __call = function(myTable, param)    --此處的param可替換其他類型的變量
      print("call " .. param)    --處理相關事件
      return "already call"
    end
})

print(myTable(num))  --myTable調用num變量

  程序運行輸出:

---------- 新建程序 ----------
call 100
already call

輸出完成 (耗時 0 秒) - 正常終止

 

六、__tostring元方法

 __tostring元方法:用於修改表的輸出行為。【類似於JAVA中類中重寫了toString()方法,用於修改對象的輸出行為

--寫法一
myTable = {10, 20, 30}

setmetatable(myTable, {
    __tostring = function(myTable)    --注意__tostring是兩個_開頭
      local sum = 0
      for _,v in pairs(myTable) do  --注意此處的_字符也表示變量,可用字母k或其他字母替代
          sum = sum + v
      end
      return ("表元素之和=" .. sum)
    end
})

print(myTable)


--寫法二 myTable = {10, 20, 30} mt = {} mt.__tostring = function(myTable) local sum = 0 for _,v in pairs(myTable) do   sum = sum + v end return ("表元素之和=" .. sum) end setmetatable(myTable, mt) print(myTable)

  循環遍歷部分也可修改為:

for index = 1,#myTable do
    sum = sum + myTable[index]
end

  程序運行輸出:

---------- 新建程序 ----------
表元素之和=60

輸出完成 (耗時 0 秒) - 正常終止

   

  明天就要去出差了、、、在這之前。。把我和Lua的相知篇趕出來和大家分享。。。

希望多少能夠給大家帶來一點幫助。。。

  如果博友們看出了我在認知Lua的過程中,,,對Lua有誤解。。。說出來、、、

我們一起探討探!!!  *^_^*

  如果覺得此博文寫的還行、看着還不錯的博友們。。。移動起你們的鼠標。。。輕輕一點推薦

把祝福傳給我們。。。讓知識傳遞下去。。。 *^_^* *^_^* *^_^*

  有想關注和閱讀我最新博文的博友們。。。就關注走一波咯。。。

   

       喜歡和愛是有差別的。。。

     喜歡是讓自己高興,,,愛卻是讓對方幸福。。。

    喜歡是一種占有,,,愛更多的是一種付出,一種責任。。。

  想要看起來毫不費力,,,在這之前你就必須全力以赴。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM