最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Lua中設(shè)置table為只讀屬性的方法詳解

 更新時(shí)間:2017年07月07日 08:42:07   作者:vanishfan  
這篇文章主要給大家介紹了關(guān)于Lua中設(shè)置table為只讀屬性的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。

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

--[[------------------------------------------------------------------------------
-** 設(shè)置table只讀 出現(xiàn)改寫會(huì)拋出lua error
-- 用法 local cfg_proxy = read_only(cfg) retur cfg_proxy
-- 增加了防重置設(shè)置read_only的機(jī)制
-- lua5.3支持 1)table庫(kù)支持調(diào)用元方法,所以table.remove table.insert 也會(huì)拋出錯(cuò)誤,
--  2)不用定義__ipairs 5.3 ipairs迭代器支持訪問(wèn)元方法__index,pairs迭代器next不支持故需要元方法__pairs
-- 低版本lua此函數(shù)不能完全按照預(yù)期工作
*]]
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

測(cè)試代碼如下:

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=t1

local t3 = read_only(t1)

print(t3.d, t3.c.e, t3.c.c.b.t2.fdsf)
function q1() t3.d = 4555 end
function q2() t3.c.d = 90 end
function q3() t3.c.c.b.t2.fdsf =90 end
function q4() table.remove(t3.a) end
function q5() t3.b[ddss] = nil end
function q6() t3[f] = 89 end
function q7() table.insert(t3.a, 999) end

print(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)
end
for k,v in pairs(t3.a) do
 print("===pairs t3.a:",k,v)
end
for k,v in ipairs(t3) do
 print("===ipairs t3:",k,v)
end
for k,v in ipairs(t3.a) do
 print("===ipair t3.a",k,v)
end
print("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)

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

string table: 0x20d4ba0
false input:17: error write to a read-only table with key = d
false input:17: error write to a read-only table with key = d
false input:17: error write to a read-only table with key = fdsf
false input:17: error write to a read-only table with key = 2
false input:17: error write to a read-only table with key = nil
false input:17: error write to a read-only table with key = nil
false 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 89
len t3: 0
len t3.a: 2
table: 0x20d4870 table: 0x20d4870
table: 0x20d5690 table: 0x20d5690 table: 0x20d1140

代碼思路設(shè)計(jì):

1.使用proxy={}空表而不是目標(biāo)表tbl來(lái)設(shè)置__newindex是因?yàn)開_newindex必須在原表里面不存在才會(huì)調(diào)用,這樣就依然可以對(duì)已存在的字段進(jìn)行改寫

__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存儲(chǔ)已經(jīng)設(shè)置過(guò)proxy的table的映射

3.對(duì)于原表tbl的訪問(wèn)使用__index=tbl

4.對(duì)于表查長(zhǎng)度使用__len= function () return #tbl end

5.對(duì)于遍歷pairs,查到lua5.3的pairs默認(rèn)迭代器next不支持訪問(wèn)元表__index,故直接__pairs = function () return pairs(tbl) end,以此來(lái)生成對(duì)目標(biāo)表的迭代遍歷

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

     8.2 – Changes in the Libraries

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

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

      8.2 – Changes in the Libraries

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

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

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • Lua教程(六):編譯執(zhí)行與錯(cuò)誤

    Lua教程(六):編譯執(zhí)行與錯(cuò)誤

    這篇文章主要介紹了Lua教程(六):編譯執(zhí)行與錯(cuò)誤,本文講解了、C代碼、錯(cuò)誤、錯(cuò)誤處理與異常、錯(cuò)誤消息與追溯等內(nèi)容,需要的朋友可以參考下
    2015-04-04
  • 使用Lua作為C語(yǔ)言項(xiàng)目的配置文件實(shí)例

    使用Lua作為C語(yǔ)言項(xiàng)目的配置文件實(shí)例

    這篇文章主要介紹了使用Lua作為C語(yǔ)言項(xiàng)目的配置文件實(shí)例,本文用Lua創(chuàng)建了一個(gè)配置文件,然后在C言語(yǔ)中解析它,需要的朋友可以參考下
    2015-04-04
  • Lua中字符串(string)淺析

    Lua中字符串(string)淺析

    這篇文章主要介紹了Lua中字符串(string)淺析,本文講解了字符串的聲明、連接、簡(jiǎn)單的使用方法等,是一篇入門教程,需要的朋友可以參考下
    2014-09-09
  • Lua和C++語(yǔ)言的交互詳解

    Lua和C++語(yǔ)言的交互詳解

    這篇文章主要介紹了Lua和C++語(yǔ)言的交互詳解,本文講解了C++和Lua交互,涉及到獲取Lua中普通變量的值,Lua中table的值和調(diào)用Lua中的函數(shù),需要的朋友可以參考下
    2014-09-09
  • Lua實(shí)現(xiàn)split函數(shù)

    Lua實(shí)現(xiàn)split函數(shù)

    這篇文章主要介紹了Lua實(shí)現(xiàn)split函數(shù),lua中沒(méi)有split分割字條串函數(shù),本文使用自定義函數(shù)實(shí)現(xiàn),需要的朋友可以參考下
    2015-04-04
  • Lua中的函數(shù)代碼實(shí)例

    Lua中的函數(shù)代碼實(shí)例

    這篇文章主要介紹了Lua中的函數(shù)代碼實(shí)例,本文著重講解函數(shù)的寫法以及一些小知識(shí),需要的朋友可以參考下
    2015-04-04
  • 實(shí)例講解Lua中pair和ipair的區(qū)別

    實(shí)例講解Lua中pair和ipair的區(qū)別

    這篇文章主要介紹了實(shí)例講解Lua中pair和ipair的區(qū)別,本文直接用實(shí)例代碼來(lái)講解pair和ipair的區(qū)別,需要的朋友可以參考下
    2015-04-04
  • Lua之字符串格式化例子和常用格式化參數(shù)介紹

    Lua之字符串格式化例子和常用格式化參數(shù)介紹

    這篇文章主要介紹了Lua之字符串格式化例子和常用格式化參數(shù)介紹,本文著重講解了格式化參數(shù)的作用,需要的朋友可以參考下
    2015-04-04
  • Lua中獲取table長(zhǎng)度的方法

    Lua中獲取table長(zhǎng)度的方法

    這篇文章主要介紹了Lua中獲取table長(zhǎng)度的方法,本文用多個(gè)實(shí)例講解多種情況下獲取Table長(zhǎng)度的方法,需要的朋友可以參考下
    2015-04-04
  • Lua編程中的一些基本語(yǔ)法整理

    Lua編程中的一些基本語(yǔ)法整理

    這篇文章主要介紹了Lua編程中的一些基本語(yǔ)法整理的相關(guān)資料,是Lua入門中最基礎(chǔ)的知識(shí),需要的朋友可以參考下
    2015-05-05

最新評(píng)論

浮梁县| 宁德市| 河源市| 临泽县| 巴里| 太仆寺旗| 雷州市| 廊坊市| 安西县| 大安市| 新竹市| 福州市| 西城区| 宝兴县| 蒙山县| 焦作市| 瓮安县| 河源市| 蚌埠市| 晋宁县| 康定县| 柳州市| 安徽省| 化州市| 汪清县| 福清市| 奈曼旗| 灵武市| 白山市| 本溪| 碌曲县| 长丰县| 双鸭山市| 措美县| 霍城县| 九龙坡区| 盖州市| 浦北县| 榆社县| 镇康县| 天长市|