麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 開發(fā) > 綜合 > 正文

Lua中設置table為只讀屬性的方法詳解

2024-07-21 23:05:03
字體:
來源:轉載
供稿:網(wǎng)友

項目中部分只讀表易被人誤改寫,故決定在非線上環(huán)境里對這些表附加只讀屬性,方便在出現(xiàn)誤改寫的時候拋出lua/269325.html">lua錯誤,最終版代碼如下:

--[[-------------------------------------------------------------------------------** 設置table只讀 出現(xiàn)改寫會拋出lua error-- 用法 local cfg_proxy = read_only(cfg) retur cfg_proxy-- 增加了防重置設置read_only的機制-- lua5.3支持 1)table庫支持調用元方法,所以table.remove table.insert 也會拋出錯誤,--  2)不用定義__ipairs 5.3 ipairs迭代器支持訪問元方法__index,pairs迭代器next不支持故需要元方法__pairs-- 低版本lua此函數(shù)不能完全按照預期工作*]]function read_only(inputTable) local travelled_tables = {} local function __read_only(tbl) if not travelled_tables[tbl] then  local tbl_mt = getmetatable(tbl)  if not tbl_mt then  tbl_mt = {}  setmetatable(tbl, tbl_mt)  end  local proxy = tbl_mt.__read_only_proxy  if not proxy then  proxy = {}  tbl_mt.__read_only_proxy = proxy  local proxy_mt = {   __index = tbl,   __newindex = function (t, k, v) error("error write to a read-only table with key = " .. tostring(k)) end,   __pairs = function (t) return pairs(tbl) end,   -- __ipairs = function (t) return ipairs(tbl) end, 5.3版本不需要此方法   __len = function (t) return #tbl end,   __read_only_proxy = proxy  }  setmetatable(proxy, proxy_mt)  end  travelled_tables[tbl] = proxy  for k, v in pairs(tbl) do  if type(v) == "table" then   tbl[k] = __read_only(v)  end  end end return travelled_tables[tbl] end return __read_only(inputTable)end

測試代碼如下:

local t0 = {k = 1}local t2 = { fdsf = {456}}local t1 = {  a = {456, 89},  b = {456,ddss = 9, t2 = t2},  d = 45,  e = "string",}t1.c=t1local t3 = read_only(t1)print(t3.d, t3.c.e, t3.c.c.b.t2.fdsf)function q1() t3.d = 4555 endfunction q2() t3.c.d = 90 endfunction q3() t3.c.c.b.t2.fdsf =90 endfunction q4() table.remove(t3.a) endfunction q5() t3.b[ddss] = nil endfunction q6() t3[f] = 89 endfunction q7() table.insert(t3.a, 999) endprint(pcall(q1))print(pcall(q2))print(pcall(q3))print(pcall(q4))print(pcall(q5))print(pcall(q6))print(pcall(q7))print(t3.a[1])for k,v in pairs(t3) do print("===pairs t3:",k,v)endfor k,v in pairs(t3.a) do print("===pairs t3.a:",k,v)endfor k,v in ipairs(t3) do print("===ipairs t3:",k,v)endfor k,v in ipairs(t3.a) do print("===ipair t3.a",k,v)endprint("len t3:",#t3)print("len t3.a:", #t3.a)local t4 = read_only(t2)local t5 = read_only(t0)local t6 = read_only(t0)print(t3.b.t2, read_only(t2))print(t5, t6, t0)

測試環(huán)境https://www.lua.org/cgi-bin/demo  lua5.3.4:

string table: 0x20d4ba0false input:17: error write to a read-only table with key = dfalse input:17: error write to a read-only table with key = dfalse input:17: error write to a read-only table with key = fdsffalse input:17: error write to a read-only table with key = 2false input:17: error write to a read-only table with key = nilfalse input:17: error write to a read-only table with key = nilfalse input:17: error write to a read-only table with key = 3===pairs t3: e string===pairs t3: b table: 0x20ccd60===pairs t3: a table: 0x20d4e70===pairs t3: d 45===pairs t3: c table: 0x20ca700===pairs t3.a: 1 456===pairs t3.a: 2 89===ipair t3.a 1 456===ipair t3.a 2 89len t3: 0len t3.a: 2table: 0x20d4870 table: 0x20d4870table: 0x20d5690 table: 0x20d5690 table: 0x20d1140

代碼思路設計:

1.使用proxy={}空表而不是目標表tbl來設置__newindex是因為__newindex必須在原表里面不存在才會調用,這樣就依然可以對已存在的字段進行改寫

__newindex: The indexing assignment table[key] = value. Like the index event, this event happens when table is not a table or when key is not present in table. The metamethod is looked up in table.Like with indexing, the metamethod for this event can be either a function or a table. If it is a function, it is called with table, key, and value as arguments. If it is a table, Lua does an indexing assignment to this table with the same key and value. (This assignment is regular, not raw, and therefore can trigger another metamethod.)Whenever there is a __newindex metamethod, Lua does not perform the primitive assignment. (If necessary, the metamethod itself can call rawset to do the assignment.)

2.避免出現(xiàn)table的互相引用,加入travelled_tables存儲已經(jīng)設置過proxy的table的映射

3.對于原表tbl的訪問使用__index=tbl

4.對于表查長度使用__len= function () return #tbl end

5.對于遍歷pairs,查到lua5.3的pairs默認迭代器next不支持訪問元表__index,故直接__pairs = function () return pairs(tbl) end,以此來生成對目標表的迭代遍歷

6.對于ipairs,查到lua5.3 ipairs函數(shù)生成的迭代器默認就支持訪問元表__index,故不需要添加__ipairs

     8.2 – Changes in the Libraries

     •The ipairs iterator now respects metamethods and its __ipairs metamethod has been deprecated.

7.對于table.insert , table.remove不用特殊處理,lua5.3的table lib支持元表操作,故依然會拋錯

      8.2 – Changes in the Libraries

      •The Table library now respects metamethods for setting and getting elements.

8.避免重復創(chuàng)建read_only,每個tbl只創(chuàng)建一個proxy代理,在tbl的metatable里和proxy的metatable里都設置屬性__read_only_proxy,可以直接訪問獲得

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對VeVb武林網(wǎng)的支持。


注:相關教程知識閱讀請移步到lua頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 日本成年免费网站 | 久草手机视频在线观看 | 亚洲国产精品久久久久制服红楼梦 | 国产污污视频 | 曰韩一二三区 | 海外中文字幕在线观看 | 一本色道久久综合亚洲精品图片 | 午夜小网站 | 精品国产一区二区三 | 黄色免费播放网站 | 亚洲精品一区二区三区大胸 | 久久久噜噜噜久久熟有声小说 | 免费观看视频在线 | 国产精品久久久久久久午夜片 | 99这里有精品 | 亚洲人成在线播放网站 | 毛片视频免费播放 | 国产一区日韩一区 | 日韩剧情片 | 欧美一级aa免费毛片 | 亚洲精品一区二区三区在线看 | 欧美aaa | 国产一区视频在线免费观看 | 一级黄片毛片免费看 | 成人免费乱码大片a毛片视频网站 | 欧美激情图区 | 亚州精品天堂中文字幕 | av在线免费不卡 | 精品xxxx户外露出视频 | 老司机一级毛片 | 久久亚洲线观看视频 | 国产亚洲欧美日韩在线观看不卡 | 国产精品久久久久一区二区 | 色淫视频 | v片在线看 | 黄色片免费看网站 | 午夜视频在线免费观看 | 国产精品久久久毛片 | 羞羞网站在线看 | 一级毛片免费一级 | 热@国产 |