在絕大多數狀況下,咱們都不會用到rawget和rawset。html
本文的運行環境:lua 5.3 for windows編程
rawset是在設置值的過程,進行處理,好比:當某個值改變時,觸發事件。或修改某個key爲新值。windows
來看看rawset函數的定義函數
--- Sets the real value of `table[index]` to `value`, without invoking the --- `__newindex` metamethod. `table` must be a table, `index` any value --- different from **nil** and NaN, and `value` any Lua value. ---@param table table ---@param index any ---@param value any function rawset(table, index, value) end
看個例子,設置過__newindex以後,就不會調用__index了?測試
local tb = {} setmetatable(tb, { __index = function() return "not find" end }) setmetatable(tb, { __newindex = function(table, key, value) local patchKey = "version" if key == patchKey then rawset(table, patchKey, "補丁值") else rawset(table, key, value) end end }) tb.version = "正常版本" tb.date = "2018" print(tb.version) --打印 補丁值 print(tb.server) --打印nil,不會調用__index方法了? print(tb.date) --打印2018
通過個人測試後, 發現lua
---若是把__index放在__newindex以後,調用不存在值,纔會調用__index方法 若是在__index在__newindex以前,則不會調用
rawget是爲了繞過__index而出現的,直接點,就是讓__index方法的重寫無效code
來看看rawget函數的定義server
--- Gets the real value of `table[index]`, the `__index` metamethod. `table` --- must be a table; `index` may be any value. ---@param table table ---@param index any ---@return any function rawget(table, index) end
編寫一個例子,測試rawget繞過__index方法htm
local tb = {} setmetatable(tb, { __index = function() return "not find" end }) tb.version = "正常版本" print(tb.version) print(tb.server) ---不存在的值,調用__index方法 --rawget是爲了繞過__index而出現的,直接點,就是讓__index方法的重寫無效 print(rawget(tb, "version")) --打印 正常版本 print(rawget(tb, "server")) --打印nil
__newindex能夠和rawset配合使用,也能夠單獨使用對象
當爲表分配值時,解釋器會查找__newindex方法,若是存在,則解釋器會調用它。
結合使用 __index和 __newindex,容許lua有強大的構造,從只讀表,到具備默認值的表,到面向對象編程的繼承
文檔:https://www.lua.org/pil/13.4.2.html
在lua5.3中,直接使用tableA.__index = function() end 設置,我這邊測試,並不會生效
local tempTable = { memberB = "test" } tempTable.__index = function() return "not find" end print(tempTable.memberA) --打印 nil print(tempTable.memberB) --打印test
而經過這種方式就正常
local tempTable = { memberB = "test" } ---__index定義了當key查找不到的行爲 setmetatable(tempTable, { __index = function() return "not find" end }) print(tempTable.memberA) --打印 not find print(tempTable.memberB) --打印test