1. 程式人生 > >lua的元表與元方法

lua的元表與元方法

方法 int 找到 註意 dex index cnblogs 沒有 val

setmetatable()函數設置元表,getmetatable()函數獲取元表

給一個table添加元表:

t = {}

t_metatable = {__index = {key = "value"}}

setmetatable(t, t_metatable)

這個有什麽用呢?

t裏面是沒有key這個鍵的,像這樣定義了元表的話(__index是元方法,表示索引,他可以是一個table,也可以是一個function,如果是table的話就在table中取值,如果是function的話值為返回值,如果未定義__index則為nil)

就會找到元表裏面去

print(t.key)

輸出:value

Lua查找一個表元素時的規則,其實就是如下3個步驟:

  • 1.在表中查找,如果找到,返回該元素,找不到則繼續
  • 2.判斷該表是否有元表,如果沒有元表,返回nil,有元表則繼續。
  • 3.判斷元表有沒有__index方法,如果__index方法為nil,則返回nil;如果__index方法是一個表,則重復1、2、3;如果__index方法是一個函數,則返回該函數的返回值。

上面的描述表示元表是可以嵌套的:

__index為一個函數,Lua就會調用那個函數,table和鍵會作為參數傳遞給函數,最終鍵值為函數的返回值(鍵是直接傳進去的,如果嵌套了多個元方法,則只能傳入上一層的表)

--只會傳入上一層的table
t = setmetatable({key = 1}, {__index = setmetatable({}, {__index = setmetatable({},{__index = function(t, key) if key == "key2" then return "abc" else return nil end end })})}) print(t.key2)

註意key可以傳進去,但是table只能傳上一層的。如果改為return t.key 的話返回為nil

但是如果這樣的話:

t = setmetatable({key = 1}, {__index = setmetatable({}, {__index = setmetatable({key = 2},{__index = function(t, key)
              if key == "key2" then
                return t.key
              else
                return nil
              end
            end
            })})})
print(t.key2)

輸出為 2

又如:

mytable = setmetatable({key1 = "value1"},{
    __index = function(mytable, key)
      if key == "key2" then
        return mytable.key1
      else
        return nil
      end
    end
  })
print(mytable.key1, mytable.key2)

這裏打印都是value1,表示獲取mytable成功。也即是說__index元方法會傳入table和key。table只能傳入上一層的

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

lua的元表與元方法