[轉]LUA元表

來源:互聯網
上載者:User

標籤:

lua中每個值都有一個元表,talble和userdata可以有各自獨立的元表,而其它類型的值則共用其類型所屬的單一元表。lua在建立table時不會建立元表。

t = {}print(getmetatable(t))  --顯示過元表 此時是nil--可以用setmetatable來設定或修改任何table的元表t1 = {}setmetatable(t,t1)assert(getmetatable(t) == t1)

任何table可以作為任何值的元表,而一組相關的table可以共用一個通用的元表,此元表描述了一個共同的行為。一個tabel甚至可以作為它自己的元表,用於描述其特有行為。

在lua中,只能設定table的元表。要設定其它類型的元表,必須通過C代碼來完成

print(getmetatable("hi"))  --005DECD8 說明字串有元表print(getmetatable(10))  --number沒有元表
13.1  算術類的元方法
Set = {}  --集合local mt = {}  --集合元表--根據參數列表中的值建立一個新的集合function Set.new(l)    local set = {}    setmetatable(set,mt)  --指定 table set的元表為mt    for k,v in ipairs(l) do        set[v] = true    --注意,是拿索來當資料用的    end    return setendfunction Set.union(a,b)    local res = Set.new{}    for k,v in pairs(a) do res[k] = true end    for k,v in pairs(b) do res[k] = true end    return resendfunction Set.intersection(a,b)    local res = Set.new{}    for k,v in pairs(a) do        if b[k] then            res[k] = true        end    end    return resendfunction Set.tostring(set)    local l = {}    for k,v in pairs(set) do        l[#l + 1] = k    end    return "{" .. table.concat(l,", ") .. "}"endfunction Set.print(s)    print(Set.tostring(s))end--將元方法加入元表mt.__add = Set.union   --指定加號為求並集的方法mt.__mul = Set.intersection  --指定乘號為交集的方法s1 = Set.new{11,22,31,44,56}s2 = Set.new{66,33,22,31}s3 = s1 + s2 --求並集   Set.print(s3) --輸出 {11, 31, 66, 22, 33, 56, 44}s4 = s1 * s2 --求交集Set.print(s4) --輸出 {31, 22}
13.2 關係類元方法

關係是指 __eq(等於)、__lt(小於)等

mt.__le = function(a,b)     for k in pairs(a) do        if not b[k] then  return false end     end     return trueendmt.__lt = function(a,b)    return a<=b and not (b<=a)endmt.__eq = function(a,b)    return a<=b and b<=aendss1 = Set.new{2,4}ss2 = Set.new{4,10,2}print(ss1<=ss2)  --trueprint(ss1<ss2)   --trueprint(ss1>=ss1)  --trueprint(ss1>ss1)   --falseprint(ss1 == ss2*ss1)  --true
13.3 庫定義的元方法

tostring是一個典型的執行個體。它能將各種類型的值表示為簡單的文字格式設定

print({}) ----table: 003ECEF0

函數總是調用tostring來格式化輸出。當格式化任意值時,tostring會檢測該值是否有一個 __tostring元方法。如果有,他就調用這個方法用來作為tostring的傳回值

在集合執行個體中,我們定議了將任命表示為字串的方法,我們可以設定元表的__tostring欄位

mt.__tostring = Set.tostring
sstext = Set.new{33,55,6666}print(sstext)  --{55, 33, 6666}

假設想要保護集合的元表,使使用者即不能看也不能修改集合的元表。那麼就需要用到__metatable。當設定了該欄位時,getmetatable就會返回這個欄位的值,而setmetatable會引發一個錯誤

mt.__metatable = "not your business"sstext1 = Set.new{}  print(getmetatable(sstext1))  --not your businesssetmetatable(s1,{})
13.4 table 訪問的元方法13.4.1 __index元方法

當訪問一個table中不存在的欄位中時,如果這個欄位不存在得到nil,但是如果這個table有一個元方法__index那麼如果沒有這個欄位,就由這個元方法來提供結果

Window = {}Window.prototype = {x=0,y=0,width = 100,height = 100}Window.mt = {}function Window.new(o)    setmetatable(o,Window.mt)    return oend--現在定義一個元方法Window.mt.__index = function(table,key)    return Window.prototype[key]endw = Window.new{x=10,y=20}print(w.width)  -- 100 window實際上沒有width這個欄位

__index元方法還可以是一個table

13.4.2  __newindex元方法

與__index不同的是__index是在查詢的時候用的而_newindes是在更新的時候用的

13.4.3具有預設值的table

以下代碼為table設定預設值

function setDefault(t,d)    local mt = {__index = function() return d end}    setmetatable(t,mt)end
13.4.4 跟蹤table的訪問

__index和__newindex都是在table中沒有所需的index才發揮作用。因為只有table保持空才能捕捉到所有對他的訪問,為了監視一個table的所有訪問就得為真正的 table 建立一個代理

 

t_src = {}  --要跟蹤的表local _t = t_srct = {} --建立代理--建立元表local mt = {    __index = function(t,k)        print("*access to element "  .. tostring(k))        return _t[k]    end,    __newindex = function(t,k,v)        print("*update of element " .. tostring(k) .. " to " .. tostring(v))        _t[k] = v    end}setmetatable(t,mt)t[2]  = "hello"  -- *update of element 2 to helloprint(t[2])  --*access to element 2
13.4.5 唯讀table

唯讀table與上一節跟蹤table類似,是通過__newindex來限制修改table記憶體

[轉]LUA元表

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.