當訪問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 不存在或拒絕訪問 系統無...