Lua metatable (Metatable) __newindex one

Lua metatable (Metatable) __newindex one

The __newindex metamethod is used to update the table, and __index is used to access the table.
When you assign a missing index to a table, the interpreter looks for the __newindex metamethod:
if it exists, it calls this function without assigning.

-- 表
bird = {
    
    }
bird.color = "red"

-- 上面说的缺少的索引是什么?
-- 表 bird 只有一个 color索引建
-- 现在要添加一个 wing
-- bird.wing = 2,此时 wing 就是bird 缺少的索引建

setmetatable(bird, {
    
    
    __newindex = function(table, key, value)
	    print("----------------------")
	    for k, v in pairs(table) do
		    print(k.."  "..v)
		end

		print("key:"..key.."   value:"..value)
        print("----------------------")

    end
})

bird.color = "yellow"
print("bird.color:"..bird.color)
-- 输出:color  yellow
-- bird.color 修改值成功

bird.wing = 2
-- 输出:
----------------------
color  red
key:wing   value:2
----------------------

print("bird.wing:"..tostring(bird.wing))
-- 输出:bird.wing:nil

Why does the table bird add a new index bird.wing = 2 to call the anonymous function function(table, key, value)
and the final result of bird.wing is nil, which is a failure to add
because when adding a metatable and calling setmetatable , an anonymous function is assigned to __newindex function(table, key, value)
When adding a new index bird.wing = 2, it calls __newindex , and then starts the anonymous function **function(table, key, value)** There is no assignment operation in the function, so add a new index key failed

So what's the point of assigning __newindex to a function as above?
If you want to make a table, you are not allowed to add new index keys, only allow to use and modify the existing index,
as above
bird.color = "yellow", the value of the color of the existing index can be read and modified
bird.wing = 2 , the newly added index is built as wing, it is not allowed to add,
then using __newindex will be able to achieve the purpose at this time

the code

-- 表
bird = {
    
    }
bird.color = "red"

animation = {
    
    }
animation.leg = 4

--(1)
animation.__newindex = animation
setmetatable(bird, animation)

--(2)
bird.wing = 2
print("bird.wing:"..tostring(bird.wing))
-- 输出:nil
print("animation.wing:"..tostring(animation.wing))
-- 输出:2

-- (3)
animation.__index = animation
bird.wing = 2
print("bird.wing:"..tostring(bird.wing))
-- 输出:2
print("animation.wing:"..tostring(animation.wing))
-- 输出:2

Explain the above code
(1) part
animation.__newindex = animation
table animation meta-method __newindex assignment to itself
Set the bird 's meta-table to animation
setmetatable(bird, animation)

(2) Part
bird.wing = 2 Add a new index key to the bird table , first check whether there is a wing index built in bird, if there is, assign the value directly, and exit
If there is no wing index key, start calling the meta-method __newindex to find the table animation , then When adding the wing index key to the table animation , the print method
below prints print(“bird.wing:”…tostring(bird.wing)) bird.wing is nil

print(“animation.wing:”…tostring(animation.wing))
animation.wing 为 2

(3) part of
animation.__index = animation assigns the meta-method __index of
table animation to animation
bird.wing = 2 logic same as (2) part of
print(“bird.wing:”…tostring(bird.wing)) at this time, Because the wing index key is added to the table animation , when bird wants to access wing , it will access __index and then look up the wing key in the table animation , and the result can be obtained

the code

bird = {
    
    }
bird.color = "red"

animation = {
    
    }
animation.leg = 4

setmetatable(bird, {
    
    __newindex = animation})

bird.wing = 2
print("bird.wing:"..tostring(bird.wing))

-- 输出:nil
print("animation.wing:"..tostring(animation.wing))
-- 输出:2

print()

Explain that the above code
setmetatable(bird, {__newindex = animation})
sets the metatable, creates a new anonymous table {__newindex = animation} , and assigns the __newindex of the anonymous table to animation

When bird.wing = 2 is called , bird finds that it does not have a wing index key, calls __newindex
of the anonymous table , and then finds animation . At this time , add a new index key wing to animation and assign a value of 2.

print(“bird.wing:”…tostring(bird.wing))
gets the value of bird.wing , bird has no index key wing and
bird cannot access animation through __index , so bird.wing is an invalid value

the code

bird = {
    
    }
bird.color = "red"

animation = {
    
    }
animation.leg = 4

local biology = {
    
    }
biology.__newindex = animation

setmetatable(bird, biology)

bird.wing = 2
print("bird.wing:"..tostring(bird.wing))
-- 输出:nil

print("biology.wing:"..tostring(biology.wing))
-- 输出:nil

print("animation.wing:"..tostring(animation.wing))
-- 输出:2

Explain the above code
local biology = {}
biology.__newindex = animation

creates a new table biology and assigns the __newindex of table biology to animation

setmetatable(bird, biology)
assignment metatable

bird.wing = 2 Search in the bird table and cannot find the wing index key,
and then access biology , and the table biology accesses animation from __newindex , then animation adds a new index key wing and assigns a value of 2 to get the wing value from the three tables as follows – bird.wing: nil - biology.wing: nil - animation.wing: 2




the code

local bird = {
    
    }
bird.color = "red"

local animation = {
    
    }
animation.leg = 4
animation.__index = animation


local biology = {
    
    }
biology.breathe = true
biology.__index = biology
biology.__newindex = animation


-- 给 biology 赋值元表 为 animation
setmetatable(biology, animation)

-- 给 bird 赋值元表为 biology
setmetatable(bird, biology)

bird.wing = 2
print("bird.wing:"..tostring(bird.wing))
-- 输出:2

print("animation.wing:"..tostring(animation.wing))
-- 输出:2

print("biology.wing:"..tostring(biology.wing))
-- 输出:2

print()

bird.color = "yellow"

print("bird.color:"..tostring(bird.color))
-- 输出:bird.color:yellow

print("bird.breathe:"..tostring(bird.breathe))
-- 输出:bird.breathe:true
-- breathe 是从 biology 继承过来的

print("bird.leg:"..tostring(bird.leg))
-- 输出:bird.leg:4
-- leg 是从 animation 继承过来的

print("biology.leg:"..biology.leg)
-- 输出:biology.leg:4
-- leg 是从 animation 继承过来的

Code explanation
via
animation.__index = animation

biology.__index = biology
biology.__newindex = animation

– Assign metatable to biology as animation
setmetatable(biology, animation)

– Assign the metatable to bird as biology
setmetatable(bird, biology)

Connect the three tables in series. According to the inheritance relationship,
biology inherits
bird and inherits biology.

Bird can get the index keys and functions of biology and animation .
Biology can get the index keys and functions of animation .

Guess you like

Origin blog.csdn.net/LIQIANGEASTSUN/article/details/127472457
one
ONE