成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Metatable In Lua 淺嘗輒止

開發 前端
Lua中Metatable這個概念, 國內將他翻譯為元表. 元表為重定義Lua中任意一個對象(值)的默認行為提供了一種公開入口. 如同許多OO語言的操作符重載或方法重載. Metatable能夠為我們帶來非常靈活的編程方式.

什么是Metatable

Lua中Metatable這個概念, 國內將他翻譯為元表. 元表為重定義Lua中任意一個對象(值)的默認行為提供了一種公開入口. 如同許多OO語言的操作符重載或方法重載. Metatable能夠為我們帶來非常靈活的編程方式.

具體的說, Lua中每種類型的值都有都有他的默認操作方式, 如, 數字可以做加減乘除等操作, 字符串可以做連接操作, 函數可以做調用操作, 表可以做表項的取值賦值操作. 他們都遵循這些操作的默認邏輯執行, 而這些操作可以通過Metatable來改變. 如, 你可以定義2個表如何相加等.

看一個最簡單的例子, 重定義了2個表的加法操作. 這個例子中將c的__add域改寫后將a的Metatable設置為c, 當執行到加法的操作時, Lua首先會檢查a是否有Metatable并且Metatable中是否存在__add域, 如果有則調用, 否則將檢查b的條件(和a相同), 如果都沒有則調用默認加法運算, 而table沒有定義默認加法運算, 則會報錯.

  1. --定義2個表 
  2. a = {5, 6}   b = {7, 8}   
  3. --用c來做Metatable   
  4. c = {}   
  5. --重定義加法操作   
  6. c.__add = function(op1, op2)   
  7. for _, item in ipairs(op2) do   
  8. table.insert(op1, item)   end   
  9. return op1   end   
  10. --將a的Metatable設置為c   
  11. setmetatable(a, c)   
  12. --d現在的樣子是{5,6,7,8}   d = a + b 

有了個感性的認識后, 我們看看Metatable的具體特性.

  Metatable并不神秘, 他只是一個普通的table, 在table這個數據結構當中, Lua定義了許多重定義這些操作的入口. 他們均以雙下劃線開頭為table的域, 如上面例子的__add. 當你為一個值設置了Metatable, 并在Metatable中設置了重寫了相應的操作域, 在這個值執行這個操作的時候就會觸發重寫的自定義操作. 當然每個操作都有每個操作的方法格式簽名, 如__add會將加號兩邊的兩個操作數做為參數傳入并且要求一個返回值. 有人把這樣的行為比作事件, 當xx行為觸發會激活事件自定義操作.

  Metatable中定義的操作add, sub, mul, div, mod, pow, unm, concat, len, eq, lt, le, tostring, gc, index, newindex, call...

  在Lua中任何一個值都有Metatable, 不同的值可以有不同的Metatable也可以共享同樣的Metatable, 但在Lua本身提供的功能中, 不允許你改變除了table類型值外的任何其他類型值的Metatable, 除非使用C擴展或其他庫. setmetatable和getmetatable是***一組操作table類型的Metatable的方法.

  Metatable與面向對象

  Lua是個面向過程的語言, 但通過Metatable可以模擬出面向對象的樣子. 其關鍵就在于__index這個域. 他提供了表的索引值入口. 這很像重寫C#中的索引器, 當表要索引一個值時如table[key], Lua會首先在table本身中查找key的值, 如果沒有并且這個table存在一個帶有__index屬性的Metatable, 則Lua會按照__index所定義的函數邏輯查找. 仔細想想, 這不正為面向對象中的核心思想繼承, 提供了實現方式么. Lua中實現面向對象的方式非常多, 但無論哪種都離不開__index.

  這個例子中我使用了ProgrammingInLua中的實現OO的方式, 建立了Bird(鳥)對象, 擁有會飛的屬性, 其他鳥對象基于此原型, Ostrich(鴕鳥)是鳥的一種但不會飛. 結果很明顯, Bird和Ostrich分別有獨立的狀態.

  1. local Bird = {CanFly = true
  2.   function Bird:New() 
  3.   local b = {} 
  4.   setmetatable(b, self) 
  5.   selfself.__index = self 
  6.   return b 
  7.   end 
  8.   local Ostrich = Bird:New() --Bird.CanFly is true, Ostrich.CanFly is true 
  9.   Ostrich.CanFly = false --Bird.CanFly is true, Ostrich.CanFly is false 

__newindex與__index相對應, 在對table的key做更新時觸發. 可以使用rawset和rawget對table的key操作來跳過這些事件的觸發.

調用與截獲

Java與C#中需要費不少周折來實現動態代理和AOP, 類似這樣的功能在Lua中確很簡單, 雖然被限制了很多, 但你依然能夠感受到Lua的靈活. 這就是__call操作, 當值被調用時觸發.

這里我將table類型的a做了一個函數方式的調用a(), 會觸發__call. 另一個應用示例可以參見我的另一篇文章Lua中實現事件機制

  1. a = {}   
  2. function a:Func()   
  3. print("simonw")   
  4. end   
  5. c = {}   
  6. c.__call = function(t, )   
  7. print("Start")   
  8. t.Func()   
  9. print("End")   end   
  10. setmetatable(a, c)   
  11. a()   
  12. --[[   
  13. Start   
  14. simonw   
  15. End   ]] 

這里的示例都是以最簡單的方式展現, 以便能更清晰的描述核心, 更多的資料以及具體應用請參考Programming In Lua和Lua參考手冊。

原文鏈接:http://tech.it168.com/j/2008-02-15/200802151323663.shtml

責任編輯:陳四芳 來源: 來自ITPUB論壇
相關推薦

2022-11-08 09:17:21

2012-12-05 07:49:34

企業云計算基礎架構即服務IaaS

2015-07-29 09:42:09

工程師全棧工程師

2018-10-16 17:57:57

開源架構

2021-11-05 08:29:13

數據校驗Spring

2019-12-30 09:28:53

Kafka集群ZooKeeper

2022-11-18 08:18:46

QueryDSLJPASQL

2023-06-15 12:55:00

AIGC模型技術

2018-06-07 08:20:51

自動化測試移動技術云平臺

2012-12-05 07:50:37

云服務云戰略

2020-09-30 14:51:57

COVID-19云計算銀行

2013-07-24 09:33:46

Hadoop安全加密

2019-09-21 20:57:59

Android安卓開發

2011-08-23 17:33:08

LuaMetatable

2015-12-17 14:58:57

云存儲

2023-04-28 12:15:57

數據分析師業務

2015-03-04 11:09:42

微信搖一搖紅包

2023-11-27 00:40:56

2012-10-23 14:23:39

微軟是絕對的主角

2012-03-30 09:36:44

Windows 8專業版
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久久久亚洲精品 | 免费观看www7722午夜电影 | 久久久久亚洲精品中文字幕 | 亚洲欧洲在线看 | 成人免费看 | 日韩精品在线看 | 欧美一区二区三区在线观看 | 高清视频一区二区三区 | 超碰8| 日韩av三区| 国产99视频精品免视看9 | 97精品一区二区 | 国产精品日韩欧美一区二区 | 亚洲一区| 亚洲a人 | 成人不卡在线 | 精品久久久久久亚洲综合网站 | 成人在线免费观看 | 成人免费一区二区三区视频网站 | 91久久久精品国产一区二区蜜臀 | 亚洲视频二区 | 欧美1区| 婷婷国产一区 | 国产精品久久久久久久久久三级 | 久久久国产一区 | 亚洲狠狠 | 日韩精品一区二区三区中文字幕 | 亚洲网站在线播放 | 国产91av视频| 99国内精品| 日本高清在线一区 | 欧美精品一区二区免费视频 | 免费看大片bbbb欧美 | h视频在线免费 | 国产精品久久久亚洲 | 自拍偷拍亚洲欧美 | 日韩人体在线 | av天天澡天天爽天天av | 久久成人精品视频 | 国产成人免费在线 | 久久精品国产久精国产 |