lua防止訪問不存在的全域性變數

2021-07-13 11:24:00 字數 3616 閱讀 7780

當訪問lua中不存在的全域性變數時並不會報錯,而是返回nil值。在我們開發的時候稍微不注意寫錯了變數名,程式並不會報錯,類似於下面這種情況。

test = 1

print(tets)

為了防止這種情況,我們可以通過設定全域性表_g的元方法__index和__newindex來解決。

全域性表_g,所有的全域性變數和全域性函式都放在這裡面,比如上面的test=1,其實是_g.test = 1。

在這之前,我們先理解lua中的__index,__newindex,rawget,rawset方法。

網上很多講解這幾個方法的,我是從這裡直接拷貝過來的。

對lua中元表的解釋: 元表可以改變表的行為模式。

這裡舉個例子:

window = {}

window.prototype =

window.mt = {}

function window.new(o)

setmetatable(o ,window.mt)

return o

endwindow.mt.__index = window.prototype

window.mt.__newindex = function (table ,key ,value)

if key == "wangbin" then

rawset(table ,"wangbin" ,"yes,i am")

endendw = window.new

w.wangbin = "55"

print(w.wangbin)

然後,我們可以看到列印資訊是:yes,i am

原本賦值的地方是w.wangbin = "55",但是結果卻是 yes,i am。

這裡就改變了元表的行為模式。

__index是:當我們訪問乙個表中的元素不存在時,則會觸發去尋找__index元方法,如果不存在,則返回nil,如果存在,則返回結果。

window = {}

window.prototype =

window.mt = {}

function window.new(o)

setmetatable(o ,window.mt)

return o

endwindow.mt.__index = function (t ,key)

-- body

return 1000

endw = window.new

print(w.wangbin)

列印結果是:1000。

這裡可以看出,我們在new的時候,w這個表裡其實沒有wangbin這個元素的,我們重寫了元表中的__index,使其返回1000,意思是:如果你要尋找的元素,該表中沒有,那麼預設返回1000。

__newindex:當給你的表中不存在的值進行賦值時,lua直譯器則會尋找__newindex元方法,發現存在該方法,則執行該方法進行賦值,注意,是使用rawset來進行賦值,至於原因,後面會講到。

window.mt = {}

function window.new(o)

setmetatable(o ,window.mt)

return o

endwindow.mt.__index = function (t ,key)

return 1000

endwindow.mt.__newindex = function (table ,key ,value)

if key == "wangbin" then

rawset(table ,"wangbin" ,"yes,i am")

endendw = window.new

w.wangbin = "55"

print(w.wangbin)

ok,這裡的列印結果是:yes,i am。w這個表裡本來沒有wangbin這個元素的,我們重寫了元表中__newindex,並在__newindex方法中重新進行賦值操作,然後,我們對這個本不存在的原色w.wangbin進行賦值時,執行__newindex方法的賦值操作,最後,列印結果便是:yes,i am

rawget是為了繞過__index而出現的,直接點,就是讓__index方法的重寫無效。(我這裡用到"重寫"二字,可能不太對,希望能得到糾正)

window = {}

window.prototype =

window.mt = {}

function window.new(o)

setmetatable(o ,window.mt)

return o

endwindow.mt.__index = function (t ,key)

return 1000

endwindow.mt.__newindex = function (table ,key ,value)

if key == "wangbin" then

rawset(table ,"wangbin" ,"yes,i am")

endendw = window.new

print(rawget(w ,w.wangbin))

列印結果是:nil。這裡的元表中__index函式就不再起作用了。

但是rawset呢,起什麼作用呢?我們再來執行一段**。

window = {}

window.prototype =

window.mt = {}

function window.new(o)

setmetatable(o ,window.mt)

return o

endwindow.mt.__index = function (t ,key)

return 1000

endwindow.mt.__newindex = function (table ,key ,value)

table.key = "yes,i am"

endw = window.new

w.wangbin = "55"

然後我們的程式就stack overflow了。可見,程式陷入了死迴圈。因為w.wangbin這個元素本來就不存在表中,然後這裡不斷執行進入__newindex,陷入了死迴圈。

知道了上面那些概念,我們的程式就好寫了,只要重寫_g的__index和__newindex方法就可以,**如下:

local tbdefinevalue = {}

setmetatable(_g, )

function getvalue(key, default)

local flag, value = pcall(function() return _g[key] end)

if flag then

return value

else

return default

endenda = getvalue('a', 111)

print(a)

通過公共介面getvalue來定義全域性變數a,其中第二個引數為預設值。

如果訪問沒有定義的全域性變數則會報:找不到全域性變數的錯誤,這樣就可以定位到具體**寫錯了。

FreeMarker 處理不存在的變數

freemarker 不能容忍引用不存在的變數,除非明確地告訴它當變數不存在時如何處理。不論在 引用變數,都可以指定乙個預設值來避免變數丟失這種情況,通過在變數名後面跟著乙個 和預設值。就像下面的例子 當 user 從資料模型中丟失時,模板將會將user 的值表示為字串 anonymous 當然也可...

python變數名不存在 (一)處理不存在的變數

不論在 引用變數,都可以指定乙個預設值來避免變數丟失這種情況,通過在變數名 後面跟著乙個 和預設值。就像下面的例子,當 user 從資料模型中丟失時,模板將會將 user 的值表示為字串 anonymous 若 user 並沒有丟失,那麼模板就會表現 出 anonymous 不存在一樣 當然也可以在...

SQL Server不存在或拒絕訪問故障的排除

2012 05 16 11 35 王有翦 字型大小 t t某企業正常使用的一套c s模式進銷存系統,新增加的一台客戶機在連線資料庫伺服器 安裝sql server 2000 時出現故障提示 dbnetlib connectionopen connect sql server 不存在或拒絕訪問 系統無...