What is metatable
MetaTable is an important concept in Lua, and each table can be combined with metatable to change the behavior of the corresponding table.
Metatables Example
-- declare a normal relational variable lo_table =-- declare empty meta table variable lo_meta_table = {}-- Set the meta-table variable for the relationship variable T setmetatable-- get a meta-table variable for a relational variable getmetatable(lo _table)
The upper code can also be written as a line, as shown below
-- The return value of the Setmetatable function is the first parameter of the function setmetatable ({}, {})
creating complex meta-table variables
MetaTable can include anything, metatable-specific keys typically begin with, __
for example __index
__newindex
, and their values are generally functions or other table.
setmetatable ({}, { function(lo_table, key) if"foo" then return 0 Else return Table[key] End End })
__index
This is the most commonly used key for metatable.
When you access the table by key, if the key has no value, then Lua looks for the key in the table's metatable (assuming metatable) __index
. If __index
a table is included, Lua looks for the corresponding key in the table.
-- Create a meta-table variable " Lan " }-- set the meta-table variable as the setmetatable of the relationship variable ({}, {__index = lo_meta_table}) -- Print the name of the lo_table variable Lan Print (Lo_table.name) -- Print lo_table variable age nil Print (Lo_table.age)
If __index
a function is included, Lua invokes that function, and the table and key are passed as arguments to the function.
--Create a meta-table variableLo_meta_table ={Name="Lan", Action=function(param)--Body if(param = ="Student") Then Print("let education return to nature") Else Print("let Blue Gull maintain education") End End}--set the meta-table variable as a relationship variableLo_table =setmetatable({}, {__index =lo_meta_table})--the action of printing lo_table variable makes education return to essencePrint(Lo_table.action ("Student"))--Print the action of lo_table variable let Blue Gull maintain educationPrint(Lo_table.action ("Xiaohao"))--Print lo_table variable age nilPrint(Lo_table.age)
__newindex
Similarly __index
, __newindex
the value is a function or table that is used to assign a value to a key.
-- Create a meta-table variable lo_meta_table = {}-- set the meta-table variable as the setmetatable of the relationship variable ({}, {__newindex = lo_meta_table})-- Set the value of the name keyword of the lo_table variable " Lan "-- print lo_meta_table meta table variable The value value of the name keyword print(lo_meta_table.name)-- Print the value of the lo_table variable name keyword Print (Lo_table.name)
--Create a meta-table variableLo_meta_table = {}--set the meta-table variable as a relationship variableLo_table =setmetatable({}, {__newindex =function(t, key, value)if type(value) = =" Number" Then Rawset(t, key, value *value)Else Rawset(t, key, value)End End})--set the value of the name keyword for the lo_table variableLo_table.name ="Lan"--Set the value of the age keyword for the lo_table variableLo_table.age =3--Print the value of the lo_meta_table meta-table variable name keywordPrint(Lo_meta_table.name)--Print the value of the lo_table variable name keywordPrint(Lo_table.name)--Print the value of the Age keyword for the lo_meta_table meta-table variablePrint(lo_meta_table.age)--Print the value of the lo_table variable age keywordPrint(Lo_table.age)
The above code is used in rawget
and rawset
to avoid a dead loop. Using these two functions, you can avoid LUA usage __index
and __newindex
.
operator
MetaTable can be used to define operators, such as +
:
--Create a table variable that overloads the + sign behaviorLo_table =setmetatable({1,2,3}, {__add=function(Lo_table, other) new= {} --traversing elements plus other for_, Vinch Ipairs(lo_table) Do Table.insert(New, V +Other )End returnNewEnd})--Perform calculation +lo_table = lo_table +2--the results that are printedPrint(lo_table[1])Print(lo_table[2])Print(lo_table[3])
And __index
, __newindex
Unlike, __mul
a value can only be a function. With __mul
similar keys are:
__add
(+)
__sub
(-)
__div
(/)
__mod
(%)
__unm
Take negative
__concat
(..)
__eq
(==)
__lt
(<
)
__le
(<=
)
__call
__call allows you to invoke the table like a function call
setmetatable ({}, { function(t, a, B, C, whatever) return (A + B + c) * whatever
end}) Local result = T (1234)
Print (Result)
__tostring
Finally, __tostring, it can define how to convert a table to a string, often with print , because by default, when you print a table, you will see table:0x7f86f3d04d80 Such a code
Lo_table =setmetatable({1,2,3}, {__tostring=function(lo_table) sum=0 for_, Vinch Pairs(lo_table) Dosum= Sum +vEnd return "The result of the calculation is:".. sumEnd})--prints out "The result of the calculation is: 6"Print(lo_table)
Create a simple vector class of vectors
Vector ={}vector.__index=Vectorfunctionvector.new (x, y)return setmetatable({x = xor 0, y = yor 0}, Vector)End--__call Keywordssetmetatable(Vector, {__call =function(_, ...)returnVector.new (...)End })--+ operatorfunctionVector:__add (Other)-- ... Localresult = Vector (self.x + other.x,self.y +other.y)returnresultEnd--__tostring Keywordsfunctionvector:__tostring ()--Body return "x:".. Self.x."y:".. self.yEnda= Vector.new ( A,Ten) b= Vector ( -, One) C= A +bPrint(a)Print(c)
Original link: http://nova-fusion.com/2011/06/30/lua-metatables-tutorial/
[Lua] Lua Advanced Tutorial Metatables