青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 132  文章 - 51  trackbacks - 0
<2011年7月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

常用鏈接

留言簿(7)

隨筆分類

隨筆檔案

文章分類

文章檔案

cocos2d-x

OGRE

OPenGL

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

什么是Metatable 

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

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

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

--定義2個表
a = {5, 6}
b = {7, 8}
--用c來做Metatable
c = {}
--重定義加法操作
c.__add = function(op1, op2)
   for _, item in ipairs(op2) do
      table.insert(op1, item)
   end
   return op1
end
--將a的Metatable設置為c
setmetatable(a, c)
--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.

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

local Bird = {CanFly = true}

function Bird:New()
    local b = {}
    setmetatable(b, self)
    self.__index = self
    return b
end

local Ostrich = Bird:New() --Bird.CanFly is true, Ostrich.CanFly is true
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中實現類似C#的事件機制

a = {}
function a:Func()
   print("simonw")
end
c = {}
c.__call = function(t, )
   print("Start")
   t.Func()
   print("End")
end
setmetatable(a, c)
a()
--[[
Start
simonw
End
]]

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


      原文地址:http://www.cnblogs.com/simonw/archive/2007/01/17/622032.html
posted on 2011-07-01 11:48 風輕云淡 閱讀(779) 評論(0)  編輯 收藏 引用 所屬分類: Lua
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            在线一区免费观看| 一区二区三区产品免费精品久久75 | 国产精品日产欧美久久久久| 亚洲一区二三| 亚洲在线视频免费观看| 国产精品一区=区| 免费不卡在线视频| 欧美福利视频一区| 亚洲香蕉视频| 午夜精品久久久99热福利| 好男人免费精品视频| 欧美黑人多人双交| 欧美视频在线免费| 久久久夜精品| 欧美经典一区二区| 欧美在线观看视频一区二区三区| 欧美在线网站| 亚洲精品乱码久久久久久蜜桃91| 一区二区三区免费看| 黑丝一区二区| 夜夜嗨av一区二区三区四区| 亚洲欧美成人在线| 在线高清一区| 亚洲少妇自拍| 亚洲国产精品久久久久秋霞影院| av成人激情| 韩国福利一区| 亚洲一区免费在线观看| 亚洲黄色免费电影| 亚洲一二三区在线观看| 樱桃成人精品视频在线播放| 亚洲伦理自拍| 在线观看成人av| 日韩视频免费在线观看| 伊人精品成人久久综合软件| 中文国产亚洲喷潮| 亚洲精品综合| 久久精品欧美| 亚洲欧美另类久久久精品2019| 噜噜噜躁狠狠躁狠狠精品视频 | 黄色一区二区三区四区| 亚洲视频精选在线| 亚洲精品欧美精品| 久久久www| 欧美在线播放一区| 欧美午夜免费电影| 亚洲三级免费| 影音先锋日韩有码| 欧美一级理论性理论a| 亚洲免费视频在线观看| 欧美日韩国产91| 亚洲国产精品电影| 亚洲电影av在线| 久久精品国产99精品国产亚洲性色 | 性色av一区二区三区红粉影视| 欧美精品久久99| 亚洲国产高潮在线观看| 亚洲第一狼人社区| 久久久一区二区| 久久这里只有精品视频首页| 国产精品一区毛片| 性色一区二区三区| 久久久国产成人精品| 国产一区二区三区成人欧美日韩在线观看 | 国产美女精品| 午夜欧美大片免费观看| 欧美在线免费播放| 国产麻豆成人精品| 欧美一区二区三区视频在线观看| 欧美亚洲一区二区三区| 国产裸体写真av一区二区| 午夜精品亚洲| 狂野欧美激情性xxxx| 在线观看精品视频| 欧美mv日韩mv国产网站| 亚洲人成网站在线播| 亚洲一区二区视频| 久久国产乱子精品免费女| 久久久久国色av免费看影院| 狠狠色丁香婷婷综合影院| 久久久久五月天| 亚洲国产经典视频| 亚洲性视频h| 国产欧美一区二区三区国产幕精品| 亚洲欧美成人| 欧美成人有码| 亚洲午夜国产成人av电影男同| 国产精品网站在线观看| 欧美在线一区二区| 欧美黄色一级视频| 亚洲欧美不卡| 在线观看国产一区二区| 欧美日韩国产在线一区| 性欧美videos另类喷潮| 欧美电影免费观看| 亚洲尤物影院| 18成人免费观看视频| 欧美日韩精品久久| 欧美在线看片a免费观看| 亚洲国产一区二区在线| 亚洲欧美日韩国产综合| 在线成人激情黄色| 欧美视频中文字幕在线| 久久久高清一区二区三区| 日韩一区二区高清| 美女图片一区二区| 亚洲欧美精品一区| 亚洲国产综合在线| 国产欧美一区二区精品忘忧草 | 美女黄色成人网| 亚洲综合国产| 亚洲精品系列| 欧美不卡一卡二卡免费版| 欧美亚洲视频一区二区| 亚洲伦理在线观看| 黄色综合网站| 国产老女人精品毛片久久| 欧美激情一区在线观看| 久久精视频免费在线久久完整在线看| 亚洲人成人99网站| 欧美高清视频一二三区| 久久久久久久高潮| 亚洲欧美日韩国产中文| 亚洲午夜精品一区二区三区他趣| 尤物精品在线| 国产在线视频不卡二| 国产精品亚洲成人| 国产精品www色诱视频| 欧美精品一区二区三区四区 | 一本色道久久| 最新国产精品拍自在线播放| 蜜桃久久av一区| 久久综合给合| 另类天堂av| 久久伊人精品天天| 久久一区二区三区超碰国产精品| 久久av一区二区| 欧美一级专区免费大片| 欧美亚洲视频一区二区| 欧美一区二视频| 欧美一区二区日韩一区二区| 性娇小13――14欧美| 亚洲欧美一级二级三级| 欧美亚洲专区| 久久九九全国免费精品观看| 久久人人精品| 开元免费观看欧美电视剧网站| 久热精品视频在线观看| 久久综合色播五月| 女主播福利一区| 国产精品99久久久久久久久 | 一区二区三区在线免费视频| 黄色一区二区在线| 亚洲精品欧美在线| 亚洲美女色禁图| 亚洲天堂av在线免费观看| 亚洲综合社区| 久久久久久一区二区三区| 久久中文久久字幕| 亚洲国产一区二区三区高清| 99国内精品久久| 午夜精品久久99蜜桃的功能介绍| 久久av红桃一区二区小说| 久久综合给合| 欧美三级在线视频| 国产女精品视频网站免费| 国外精品视频| 99在线精品视频| 亚洲欧美影院| 美女精品一区| 99国产精品99久久久久久粉嫩| 亚洲视频播放| 狂野欧美一区| 国产精品久久影院| 伊人伊人伊人久久| 亚洲视频在线看| 久久久久久久激情视频| 亚洲国产精品久久人人爱蜜臀 | 宅男噜噜噜66国产日韩在线观看| 欧美亚洲免费| 欧美剧在线观看| 国产亚洲视频在线| 99精品视频一区| 久久综合中文色婷婷| 一区二区欧美激情| 久久全球大尺度高清视频| 欧美色网一区二区| 亚洲国产高清一区二区三区| 亚洲专区一区| 亚洲二区免费| 欧美一级二区| 国产精品毛片a∨一区二区三区| 亚洲电影毛片| 欧美一区二区女人| 一二美女精品欧洲| 欧美国产极速在线| 韩国女主播一区| 亚洲欧美日韩国产精品| 亚洲伦伦在线| 欧美sm重口味系列视频在线观看|