Lua: Talking about the understanding of metatable and metamethod


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
Rely on the environment of Lua5.1
Rely on Sublime Text3 editor

Features of this article

Full-process graphic teaching
Emphasis on practice, light theory, quick start
Provide the whole process source code content





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 table t_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

  • not equal to (a~=b -> not (a==b))
  • greater than (a>b -> b
  • Greater than or equal to (a>=b -> b<=a)

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
syntaxbug.com © 2021 All Rights Reserved.