定义
raw:原始的,未加工的。
rawset/rawget:对“原始的”表进行直接的赋值/取值操作。
所以,raw方法就是忽略table对应的metatable,绕过metatable的行为约束,强制对原始表进行一次原始的操作,也就是一次不考虑元表的简单更新。另外,一次原始的操作其实并不会加速代码执行的速度,效率一样。
格式
rawset(table, key, value)
rawget(table, key)
作用
当操作table时,如果我们有以下需求:
- 访问时,不想从 __index 对应的元方法中查询值
- 更新时,不想执行 __newindex 对应的元方法
- 在 __newindex 元方法中,设置table的key/value时,不想陷入死循环而爆栈
那么,我们可以考虑使用raw方法。
举个例子
Window = {}
Window.prototype = {x = 0 ,y = 0 ,width = 100 ,height = 100,}
Window.mt = {}
function Window.new(o)
setmetatable(o ,Window.mt)
return o
end
Window.mt.__index = function (t ,key)
return 1000
end
Window.mt.__newindex = function (table ,key ,value)
if key == "wangbin" then
rawset(table ,"wangbin" ,"yes,i am") (1)
-- table.wangbin = "yes,i am" (2)反例
end
end
w = Window.new({x = 10 ,y = 20} )
print(rawget(w ,w.wangbin))
print(w.wangbin)
w.wangbin = "nVal"
print(w.wangbin)
rawset(w,"wangbin","nVal")
print(w.wangbin)
结果输出:
nil
1000
yes,i am
nVal
如果把(1)换成(2),在第三个输出结果处报错stack overflow。因为在__newindex中设置 table.wangbin=”yes,i am”,就需要进入到table的元表,也就是又回到 __newindex,这里又要设置table.wangbin,于是进入死循环,爆栈出错。