Lua rawget rawset newindex 函數定義和例子

在絕大多數狀況下,咱們都不會用到rawget和rawset。html

本文的運行環境:lua 5.3 for windows編程

rawset 賦值操做

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 取原始值

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

__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
相關文章
相關標籤/搜索