Lua rawget rawset newindex 函式定義和例子
阿新 • • 發佈:2018-11-28
在絕大多數情況下,我們都不會用到rawget和rawset。
本文的執行環境:lua 5.3 for windows
rawset 賦值操作
rawset是在設定值的過程,進行處理,比如:當某個值改變時,觸發事件。或修改某個key為新值。
來看看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.
[email protected] table table
[email protected] index any
[email protected] 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
經過我的測試後, 發現
---如果把__index放在__newindex之後,呼叫不存在值,才會呼叫__index方法
如果在__index在__newindex之前,則不會呼叫
rawget 取原始值
rawget是為了繞過__index而出現的,直接點,就是讓__index方法的重寫無效
來看看rawget函式的定義
--- Gets the real value of `table[index]`, the `__index` metamethod. `table`
--- must be a table; `index` may be any value.
[email protected] table table
[email protected] index any
[email protected] any
function rawget(table, index) end
編寫一個例子,測試rawget繞過__index方法
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
__newindex可以和rawset配合使用,也可以單獨使用
當為表分配值時,直譯器會查詢__newindex方法,如果存在,則直譯器會呼叫它。
結合使用 __index和 __newindex,允許lua有強大的構造,從只讀表,到具有預設值的表,到面向物件程式設計的繼承
文件:https://www.lua.org/pil/13.4.2.html
Lua5.3 __index要通過setmetatable設定
在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