Latest web development tutorials

Lua table element (Metatable)

In Lua table, we can access the corresponding key value to get value, but it can not be operated on two table.

Therefore, Lua provides a table element (Metatable), table allow us to change the behavior of each action associated with the corresponding element method.

For example, using the meta table, we can define how Lua table to calculate the sum of two operations a + b.

When Lua attempt adding two tables, first check whether there are one of two yuan table, after checking whether there is a place called "__add" field, if found, then call the corresponding value. "__add" And other instant field, the corresponding value (often a function or a table) is the "Element Method."

There are two very important functions to handle yuan table:

  • setmetatable (table, metatable): set the table for the specified table element (metatable), if there __metatable key element table (metatable) in, setmetatable fail.
  • getmetatable (table): Returns the object metadata table (metatable).

The following example demonstrates how to set the table for the specified table element:

mytable = {}                          -- 普通表 
mymetatable = {}                      -- 元表
setmetatable(mytable,mymetatable)     -- 把 mymetatable 设为 mytable 的元表 

The above code can be written directly to the line:

mytable = setmetatable({},{})

Following are the return object metadata table:

getmetatable(mytable)                 -- 这回返回mymetatable

__index Element Method

This is the most commonly used metatable key.

When you pass the key to access the table, and if the key has no value, then Lua will find the table of metatable (assuming metatable) in __index key. If __index contains a table, Lua will find the corresponding key in the table.

We can use lua command to enter interactive mode Views:

$ lua
Lua 5.3.0  Copyright (C) 1994-2015 Lua.org, PUC-Rio
> other = { foo = 3 } 
> t = setmetatable({}, { __index = other }) 
> t.foo
3
> t.bar
nil

If __index contains a function, then, Lua will call that function, table and keys will be passed as a parameter to the function.

__index element method to view the table element exists, if not, return the result is nil; if it exists by __index return results.

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

print(mytable.key1,mytable.key2)

Examples of output is:

value1	metatablevalue

Analysis examples:

  • mytable table assigned{key1 = "value1"}.

  • mytable set meta table element method __index.

  • Find key1 in the mytable table, if found, return that element can not be found, continue.

  • Find key2 in the mytable table, if found, return metatablevalue, find continued.

  • Analyzing meta table has no __index method, if __index method is a function, call the function.

  • Element method to check whether incoming "key2" parameter key (mytable.key2 set), if the incoming "key2" parameter returns "metatablevalue", otherwise mytable corresponding key.

We can write the above code is simple:

mytable = setmetatable({key1 = "value1"}, { __index = { key2 = "metatablevalue" } })
print(mytable.key1,mytable.key2)

to sum up

Lua lookup rules a table element when, in fact, the following three steps:

  • 1. Find in the table, if found, return that element, not found, continue
  • 2. determine whether the table has RMB table, if there is no element table, return nil, there is continued dollar table.
  • 3. Analyzing meta table has no __index method, if __index method is nil, return nil; if __index method is a table, repeat 1,2,3; if __index method is a function, the function returns return value.

__newindex Element Method

__newindex element method is used to update the table, __ index is used to access the table.

When you give a missing index table assignment, the interpreter will look __newindex Element Method: If you call this function without assignment.

The following example demonstrates the application __newindex Element Method:

mymetatable = {}
mytable = setmetatable({key1 = "value1"}, { __newindex = mymetatable })

print(mytable.key1)

mytable.newkey = "新值2"
print(mytable.newkey,mymetatable.newkey)

mytable.key1 = "新值1"
print(mytable.key1,mymetatable.key1)

Examples of the implementation of the above output is:

value1
nil	新值2
新值1	nil

Examples of the above tables set element method __newindex, when the new index key (newkey) assignment (mytable.newkey = "new value 2"), will call element method without assignment. And if an existing index key (key1), will carry out the assignment, without calling Element Method __newindex.

The following example uses rawset function to update the table:

mytable = setmetatable({key1 = "value1"}, {
  __newindex = function(mytable, key, value)
		rawset(mytable, key, "\""..value.."\"")

  end
})

mytable.key1 = "new value"
mytable.key2 = 4

print(mytable.key1,mytable.key2)

Examples of the implementation of the above output is:

new value	"4"

Add operator for the table

The following example demonstrates two tables add operation:

-- 计算表中最大值,table.maxn在Lua5.2以上版本中已无法使用
-- 自定义计算表中最大值函数 table_maxn
function table_maxn(t)
    local mn = 0
    for k, v in pairs(t) do
        if mn < k then
            mn = k
        end
    end
    return mn
end

-- 两表相加操作
mytable = setmetatable({ 1, 2, 3 }, {
  __add = function(mytable, newtable)
    for i = 1, table_maxn(newtable) do
      table.insert(mytable, table_maxn(mytable)+1,newtable[i])
    end
    return mytable
  end
})

secondtable = {4,5,6}

mytable = mytable + secondtable
	for k,v in ipairs(mytable) do
print(k,v)
end

Examples of the implementation of the above output is:

1	1
2	2
3	3
4	4
5	5
6	6

__add key element contained in the table, and add operation. A list of actions corresponding to the following table:

mode description
__add Corresponding operator '+'.
__sub Corresponding operator '-'.
__mul Corresponding operator '*'.
__div Corresponding operator '/'.
__mod Corresponding operator '%'.
__unm Corresponding operator '-'.
__concat Corresponding operator '..'.
__eq Corresponding operator '=='.
__lt Corresponding operator '<'.
__le Corresponding operator '<='.

__call Element Method

__call element method is called when Lua calls a value. The following example illustrates the calculation table of the elements, and:

-- 计算表中最大值,table.maxn在Lua5.2以上版本中已无法使用
-- 自定义计算表中最大值函数 table_maxn
function table_maxn(t)
    local mn = 0
    for k, v in pairs(t) do
        if mn < k then
            mn = k
        end
    end
    return mn
end

-- 定义元方法__call
mytable = setmetatable({10}, {
  __call = function(mytable, newtable)
	sum = 0
	for i = 1, table_maxn(mytable) do
		sum = sum + mytable[i]
	end
    for i = 1, table_maxn(newtable) do
		sum = sum + newtable[i]
	end
	return sum
  end
})
newtable = {10,20,30}
print(mytable(newtable))

Examples of the implementation of the above output is:

70

__tostring Element Method

__tostring element method is used to modify the behavior of the output table. The following examples of our custom output table of contents:

mytable = setmetatable({ 10, 20, 30 }, {
  __tostring = function(mytable)
    sum = 0
    for k, v in pairs(mytable) do
		sum = sum + v
	end
    return "表所有元素的和为 " .. sum
  end
})
print(mytable)

Examples of the implementation of the above output is:

表所有元素的和为 60

From this article we can know Element table can be a good simplify our code function, so understanding Lua meta table allows us to write simpler excellent Lua code.