Preface What is this article talking about Talking about the understanding of Lua metatable and metamethod What is this article suitable for Suitable for beginners beginner Lua What is needed for this article Have a simple understanding of Lua syntax Features of this article Full-process graphic teaching |
Improve reading experience ? Level 1 title
? Secondary title
? Third-level title? Level 4 title
|
Table of Contents
- ? Metatable and metamethod
-
- ? Metatable
- ? Get metatable
- ? Set metatable
- ? Metamethod
-
- ? Element methods related to arithmetic operations
-
- ? A simple example of adding two tables
- ? An example of adding two sets of different data
- ? Metamethods related to relational operations
- ? Library definition related metamethod
- ? table-related metamethod
-
- ? __index element method
- ? __newindex element method
- ? Push
- ? Conclusion
? Metatable and metamethod
In my humble opinion, metatable
is the extension and supplement
of a certain data or a certain type of data in Lua, and metamethod
is A function that can be overridden with a defined function
Take the most common table as an example:
local t = {<!-- -->} local t1 = {<!-- -->} t1.__index = function(_, key) return tbl[key] end setmetatable(t, t1) print(t[key])
When we set metatable t1
for table t
, and add __index
in metatable t1
Meta method, when we get data from table t according to the key key
, if there is no data in t, then we will get the return value of __index
We will discuss metatables and metamethods in more detail below
? Metatable
-
A metatable is just a table
-
Every value (all types) in the Lua language can have a metatable
-
Each table (table) and user data type (userdata) has its own independent metatable
-
Other types share the same metatable of the same type (all strings
string
share a metatable) -
The newly created table has no metatable
-
Strings have a default unified metatable, and other types have no metatable by default
-
In the Lua code, we can only add metatables for tables, other types can be passed through c or debugging library
Note:
A table can also be its own metatable
? Get meta table
t = {<!-- -->} getmetatable(t)
Get metatable by method getmetatable
? Set metatable
t = {<!-- -->} t1 = {<!-- -->} setmetatable(t, t1)
Set t1 to the metatable of t through the method setmetatable
? Metamethod
Metatables are various behaviors defined by the main
, each behavior is associated with a corresponding metamethod, which can be simply divided into the following major types, let us briefly describe and give examples< /strong>
? Element methods related to arithmetic operations
The following table records the metamethods and their function descriptions related to arithmetic operations
Meta method name | Function description |
---|---|
__add | addition |
__sub | subtraction |
__mul | multiplication |
__div | Division |
__idiv | floor division |
__unm | Negative number |
__mod | Moulding |
__pow | exponentiation |
__band | and |
__bor | or |
__bxor | exclusive or |
__bnot | Reverse |
__shl | Shift left |
__shr | Shift right |
__concat | Connection operator |
? A simple example of adding two tables
local t_1 = {<!-- -->1,2,3} local t_2 = {<!-- -->4,5,6} local t1 = {<!-- -->} t1.__add = function(a,b) local tbl = {<!-- -->} for k,v in pairs(a) do table. insert(tbl,v) end for k,v in pairs(b) do table. insert(tbl,v) end return tbl end setmetatable(t_1, t1) local result = t_1 + t_2 print(result[1],result[2],result[3],result[4],result[5],result[6])
Let’s briefly analyze:
- We hope that the two tables can be added through the arithmetic operator
+
- Add meta table
t1
for tablet_1
- Add a metamethod
__add
to the metatable - Execute the operation of
t_1 + t_2
, we get a fusion table
Analysis of the problem:
Question 1: Why is metatable only set for table t_1
In fact, the execution of the metamethod of the arithmetic class does not require both at the same time
When the operation of+
is performed, the__add
metamethod will be retrieved from both in the order of addition
Use the first retrieved metamethod as the execution plan
Both have no__add
metamethod, and an exception will be thrown
Question 2: Combine the two with specific behavioral processing
The parameters a and b of the metamethod
__add
are the two to be added
In the method body, we can customize the fusion logic
In the above example, we create a new table containing all subsets of the parameters, and then return
? An example of adding two sets of different data
In fact, addition is only a generalized behavior, and Lua is not limited to operations between data of the same type
With the existence of metamethods, we can perform add
operations on arbitrary data
The following example we try to add table (table)
and string (string)
local t_1 = {<!-- -->1,2,3} local t_2 = "aaaaa" local t1 = {<!-- -->} t1.__add = function(a,b) local temp = "" for k,v in pairs(a) do temp = temp..v end temp = temp .. b return temp end setmetatable(t_1, t1) print(t_1 + t_2)
We only need to process different types of data in the method body of the meta method __add
In the above example, we concatenate the subset in the table and the string into a new string as the return value
Note:
Other arithmetic element methods are used in the same way as __add
in the example
? Metamethods related to relational operations
metamethod name | function description |
---|---|
__eq | equal to |
__lt | less than |
__le | less than Equal to |
There are actually only three relational operators in Lua:
- equal to (a==b)
- less than (a
- Less than or equal to (a<=b)
For the other three operations, Lua will convert them
Different from arithmetic operations:
Note:
Both relational operations must share the same metatable! !
Note:
Different data can only be compared for equality, but it will always return false
Note:
An exception will be thrown for comparison of different data except for equality
? Library definition related metamethods
It is also common practice for libraries to define and use their own fields in metatables
Common example 1: tostring
When we output print
, we will first search whether the target contains the __tostirng
metamethod, and if it exists, it will be output according to the method
Common example 2:
You can set the metatable __metatable
field so that users can neither see nor modify the metatable
? table-related metamethod
? __index element method
Similar to the get method of attributes in C#, when obtaining table values, if there is such a metamethod, if there is no corresponding key value, return the return value of __index
strong>
? __newindex element method
Similar to the set method of an attribute in C#, when assigning a value to a table, if the key value does not exist and __newindex
exists, this metamethod will be called
Note:
We can use these two meta-methods to make some restricted tables, such as read-only, write-only, immutable tables, etc.
? Push
- Github
https://github.com/KingSun5
? Conclusion
If you think the blogger’s article is well written, you may wish to pay attention to the blogger and like the blog post. In addition, the blogger’s ability is limited. If there are any mistakes in the article, you are welcome to comment and criticize.
This article is an original article, please comment and leave a message for reprinting, and the source of the famous author at the head of the reprinted article