錯誤處理非常關鍵,因為實際操作通常需要使用複雜的操作,包括檔案操作,資料庫事務和Web服務呼叫。
在任何程式設計中,總是需要錯誤處理。 錯誤可以是兩種型別,它們包括 -
由於不正確地使用各種程式元件(如運算子和表示式),從而發生語法錯誤。 語法錯誤的一個簡單範例如下所示-
a == 2
使用單個「單等於號」和「雙等於號」之間存在差異。 使用不當可能導致錯誤。 一個「等於」指的是賦值,而兩個「等於」指的是比較。
語法錯誤的另一個範例如下所示 -
for a= 1,10
print(a)
end
當執行上述程式時,將獲得以下輸出 -
lua: test2.lua:2: 'do' expected near 'print'
語法錯誤比執行時錯誤更容易處理,因為Lua直譯器比執行時錯誤更清楚地定位錯誤。 從上面的錯誤中,可以很容易地知道根據Lua結構在print
語句之前新增do
語句。
如果出現執行時錯誤,程式將成功執行,但由於輸入錯誤或錯誤處理的函式,可能會導致執行時錯誤。 顯示執行時錯誤的簡單範例如下所示。
function add(a,b)
return a+b
end
add(10)
當構建上面程式時,它將成功構建並執行。 執行後,顯示執行時錯誤。
lua: test2.lua:2: attempt to perform arithmetic on local 'b' (a nil value)
stack traceback:
test2.lua:2: in function 'add'
test2.lua:5: in main chunk
[C]: ?
這是由於未傳遞兩個引數變數而發生的執行時錯誤。 b
引數是預期的,但是因為它未傳入,預設使用的是nil
從而產生錯誤。
要處理錯誤,經常使用兩個函式是 - assert
和error
。 一個簡單的例子如下所示。
local function add(a,b)
assert(type(a) == "number", "a is not a number")
assert(type(b) == "number", "b is not a number")
return a+b
end
add(10)
當構建上面程式時,它將成功構建並執行。 執行後,顯示執行時錯誤。
lua: test2.lua:3: b is not a number
stack traceback:
[C]: in function 'assert'
test2.lua:3: in function 'add'
test2.lua:6: in main chunk
[C]: ?
error(message [,level])
終止最後一個呼叫的受保護函式,並將訊息作為錯誤訊息返回。 此函式錯誤永遠不會返回。 通常,錯誤會在訊息開頭新增有關錯誤位置的一些資訊。 level
引數指定如何獲取錯誤位置。 對於級別1
(預設值),錯誤位置是呼叫錯誤函式的位置。 級別2
將錯誤指向呼叫呼叫錯誤的函式的位置等等。 傳遞0
級可避免向訊息新增錯誤位置資訊。
在Lua程式設計中,為了避免丟擲這些錯誤和處理錯誤,需要使用pcall
或xpcall
函式。
pcall(f,arg1,...)
函式在保護模式下呼叫所請求的函式。 如果函式f
中發生某些錯誤,則不會丟擲錯誤。 它只返回錯誤狀態。 使用pcall
的一個簡單範例如下所示。
function myfunction ()
n = n/nil
end
if pcall(myfunction) then
print("Success")
else
print("Failure")
end
當構建上面程式時,它將成功構建並執行。 執行後,顯示執行時錯誤。
Failure
xpcall(f,err)
函式呼叫所請求的函式,並設定錯誤處理程式。 f
內的任何錯誤都不會傳播; 而xpcall
只捕獲錯誤,使用原始錯誤物件呼叫err
函式,並返回狀態程式碼。
xpcall
函式的一個簡單範例如下所示 -
function myfunction ()
n = n/nil
end
function myerrorhandler( err )
print( "ERROR:", err )
end
status = xpcall( myfunction, myerrorhandler )
print( status)
當執行上面的程式時,將得到以下輸出。
ERROR: test2.lua:2: attempt to perform arithmetic on global 'n' (a nil value)
false
作為程式員,最重要的是確保在編寫的程式中處理正確的錯誤處理。 使用錯誤處理可以確保處理超出邊界條件的意外條件而不會干擾程式的使用者。