Difference between tables and metatables in lua

What is the difference between tables and metatables in corona. What are the types of metatables. How to use it and where can I use it? What is the main purpose of using tables and metamaterials?

+4
source share
2 answers

Lua (which Corona is based on) uses metadata for various purposes.

Corresponding entry in the manual Section 2.8 . A good tutorial can be found here or here .

Metatable is just a table, like any other, but it is set as metatable in another table (which I will call the base table further to make the difference between the two tables).

Meta-tag can contain anything, but special keys (starting with double underscore) are interesting. The values ​​set for these keys in this table will be called up in special cases. Which event depends on which key. The most interesting are:

  • __index : will be used whenever a key in the base table is scanned but does not exist. This may contain a table in which the key will be displayed instead, or a function that will be passed to the original table and key. This can be used to implement methods in tables (OOP style), to redirect, missed cases, set default values, etc. Etc.
  • __newindex : will be used every time a new key is to be assigned in a table (which was previously zero). If it is a table, a key will be assigned in this table. If this is a function, then the original table, key and value will be passed to this function. This can be used to control access to the table, preprocess data, and redirect appointments.
  • __call : allows you to call a function that is called if you use, for example. table() .
  • __add,__sub,__mul,__div,__mod are used to implement binary operations,
  • __unm used to implement unary operations,
  • __concat used to implement concatenation (operator ..)
  • __len used to implement the length operator (#)
  • __eq,__lt,__le are used to implement comparisons

A little thing to know when using __index and co .: in these methods, you must use rawget and rawset to prevent the metamethod from being called again each time, causing a loop. As a small example:

 t={1,2,3} -- basetable mt={} -- metatable mt.__index=function(t,k) print("__index event from "..tostring(t).." key "..k) return "currently unavailable" end mt.__newindex=function(t,k,v) print("__newindex event from "..tostring(t).." key: "..k.." value: "..v) if type(k)=="string" then rawset(t,k,v:reverse()) else rawset(t,k,v) end end mt.__call=function(t,...) print("call to table "..tostring(t).." with arguments: ".. table.concat({...},',')) print("All elements of the table:") for k,v in pairs(t) do print(k,v) end end setmetatable(t,mt) t[4]="foo" -- this will run the __newindex method print(t[5]) -- this will run the __index method t("foo","bar") -- Multiple fall through example: t={} mt={} mt2={} setmetatable(t,mt) -- metatable on base table setmetatable(mt,mt2) -- second layer of metatable mt.__index=function(t,k) print('key '..k..' not found in '..namelookup[t]) return getmetatable(t)[k] end -- tries looking nonexistant indexes up in mt. mt2.__index=mt.__index -- function was written portably, reuse it. t[1]='A' mt[2]='B' mt2[3]='C' namelookup={[t]="t",[mt]="mt",[mt2]="mt2"} print(t[1],t[2],t[3],t[4]) 

Now these are just silly examples, you can do much more complex things. Take a look at the examples, take a look at the relevant chapters in Programming in Lua, and experiment. And try not to be confused;)

+12
source

Tables in Lua are the primary data type that you can use to create dynamic structured data. In other languages ​​there are arrays, lists, dictionaries (storage with a key), in Lua you only have tables. The only operations you can perform on the base table are to index and store the value using the tab[key] syntax, that is:

 local tab = {} tab['key1'] = 'Hello' -- storing a value using a string key tab.key2 = 'World' -- this is syntax sugar, equivalent to previous print(tab.key1, tab['key2']) -- indexing, the syntax is interchangable 

You cannot do anything with base tables, for example by adding them:

 local v1={x=0,y=0} local v2={x=1,y=1} print(v1+v2) --> stdin:1: attempt to perform arithmetic on local 'v1' (a table value) 

Metatable allows you to change the behavior of tables, indicate what should be done when tables are added, multiplied, combined ( .. ), etc. Metatable is just a table that contains functions with special keys, also called metamethods. You can assign a metatable to a table using setmetatable() . For instance:

 local Vector = {} -- this will be the metatable for vectors function Vector.__add(v1, v2) -- what to do when vectors are added -- create a new table and assign it a Vector metatable return setmetatable({x=v1.x+v2.x, y=v1.y+v2.y}, Vector) end function Vector.__tostring(v) -- how a vector should be displayed -- this is used by tostring() and print() return '{x=' .. vx .. ',y=' .. vy .. '}' end local v1 = setmetatable({x=1, y=2}, Vector) local v2 = setmetatable({x=3, y=4}, Vector) -- vectors are added and the resulting vector is printed print(v1 + v2) --> {x=4,y=6} 

If you want to better understand metatables, you should read the Program in the Lua chapter on meta tags .

+13
source

Source: https://habr.com/ru/post/1416094/


All Articles