Lua中rawset 函数使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhaixh_89/article/details/84305229

当我们只想单纯的调用table里的字段或者给table字段赋值时,我们可以通过rawget函数来忽略元表的__index作用,只从table中
查找例如:

    local father = {
    	--house=1,
    	sayHello = function()
            print("大家好,我是father.");
        end
    }
    
    local temp ={
        
        __index = father,
        __newindex = function(table, key)
            print(key .. "字段是不存在的,不允许给它赋值!");
        end
    }
    
    son = {
    	car=1
    }
    setmetatable(son, temp) --把son的metatable设置为father
    print(rawget(son, "house"));
    print(rawget(son, "car"));
    rawset(son, "house", "10");
    rawset(son, "sayHello", function()
            print('============')
        end);
    print(son.house);
    son.sayHello()

上面代码输出:

nil
1
10
============

rawget函数的第一个参数是要调用的table,第二个参数是table的字段名。
因此,通过rawget调用son的house字段,返回nil,而调用car字段,则能正确取得值。
同样的是,rawset函数可以忽略元表的__newindex功效,单纯地给house赋值

另外在网上看到有个人用__index和__newIndex实现了一个只读的函数,挺有意思的这里贴一下

local function readOnly(t)
    local newT = {};
    local mt = {
        __index = t,
        __newindex = function()
            error("别修改我!我是只读的!");
        end
    }
    setmetatable(newT, mt);
    return newT;
end
local days = readOnly({"星期一", "星期二", "星期日"});
  
days[2] = "星期三哪去了啊?" ;

输出:[LUA-print] LUA ERROR: [string "src/main.lua"]:130: [string "src/main.lua"]:76: 别修改我!我是只读的!

没错,通过readOnly产生的table,是无法进行赋值操作的。
 
那么,原理呢?我们来一步步思考吧:

a.首先,readOnly会创建一个新的table,然后把我们传进去的table作为__index元方法。

b.元表里还增加了__newindex,用来阻止不存在字段的赋值操作。

c.readOnly返回的table已经不是我们原来的table了,它是一个空的table,但是它被设置了一个新的元表。

扫描二维码关注公众号,回复: 4465461 查看本文章

d.开始对days执行赋值操作:days[2] = “星期三哪去了啊?” 。

e.days是一个空的table,所以它不存在这个字段,也因此,会调用__newindex元方法,赋值失败。

f.如果只是调用days,不进行赋值,如:print(days[2]); 则能正常输出字段值,因为days的元表里有__index元方法。虽然days中不存在2这个字段,但是可以通过__index找到这个字段。
 
总而言之,最终,days成为了一个只可以读取,不能进行赋值操作的table。

节选自:https://www.jb51.net/article/55160.htm

猜你喜欢

转载自blog.csdn.net/zhaixh_89/article/details/84305229