lua 收不到服务器发来消息,lua 学习之错误处理
錯誤處理
動態(tài)鏈接
在 Lua 中,動態(tài)鏈接被視為所有其他機制的母機制
因此利用它就可以動態(tài)地加載任何其他不在 Lua 中的機制
package.loadlib 所需兩個參數(shù)
庫的完整路徑
正確的函數(shù)名稱
loadlib 函數(shù)加載指定的庫,并將其鏈接入 Lua
它沒有調用庫中的任何函數(shù)
而是將一個 C 編寫的函數(shù)作為 Lua 函數(shù)返回
如果加載庫或查找初始化函數(shù)時發(fā)生錯誤,會返回 nil 及一條錯誤信息
local path = "c:/lua/5.1/socket.so"
local f = package.loadlib(path, "luaopen_socket")
通常使用 require 來加載 C 程序庫,這個函數(shù)會搜索指定的庫
然后用 loadlib 加載庫,并返回初始化函數(shù)
這個初始化函數(shù)應將庫中提供的函數(shù)注冊到 Lua 中,就類似 Lua 代碼塊中定義了其他函數(shù)
錯誤
Lua 是一種擴展語言,通常嵌入在應用程序中
如果發(fā)生錯誤時如果直接崩潰或退出,那么我們就無法捕獲到錯誤出現(xiàn)在哪里
因此 Lua 只要發(fā)生一個錯誤,就應該結束當前程序塊并返回應用程序
Lua 中任何未預期條件都會引發(fā)一個錯誤,如:
將兩個非數(shù)字的值相加
對一個不是函數(shù)的值進行調用操作
索引一個不是 Table 的值
可以通過調用 error 函數(shù),顯式地引發(fā)發(fā)一個錯誤
需要傳入一個錯誤消息的函數(shù)
do
print("enter a number:")
n = io.read("*number")
if not n then
error("invalid input")
end
end
-- 與上述代碼等效
do
print("enter a number:")
n = assert(io.read("*number"), "invalid input")
end
assert 如果第一個參數(shù)為 true 則返回該參數(shù)
如果第一個參數(shù)為 false 或 nil 就會引發(fā)一個錯誤
第二個參數(shù)為一個可選的信息字符串
在調用 assert 時會對其參數(shù)求值
下述代碼中,即使 n 是數(shù)字類型, Lua 也會進行字符串連接
n = io.read()
assert(tonumber(n), "invalid input:" .. n .. " is not a number")
當一個函數(shù)遭遇了一種未預期的情況即「異常」,可以采取兩種基本行為
返回錯誤代碼 (通常是 nil)
引發(fā)一個錯誤(調用 error)
sin 傳入 table 作為參數(shù)
-- 返回一個錯誤代碼,檢查 sin 函數(shù)返回值
local res = math.sin(x)
if not res then
end
-- 調用 sin 之前,檢查參數(shù)
if not tonumber(x) then
end
通常既不檢查參數(shù)也不會檢查 sin 的返回值
可以停止計算,然后給出錯誤消息
io.open 文件不存在的情況或拒絕訪問時的異常行為
一個文件存在與否可以用是否能夠打開來驗證
當 io.open 無法打開一個文件時,應返回 nil ,并附加一條錯誤消息
do
local file, msg
repeat
print("enter a file name:")
local name = io.read()
if not name then
return
end
-- io.open 第一個參數(shù)為文件路徑,第二個參數(shù)為打開模式,r 為字符模式
-- io.open 成功則返回文件句柄,無法打開會返回 nil 和錯誤消息
file, msg = io.open(name, "r")
if not file then
print(msg)
end
until file
end
-- 等效于上述代碼.錯誤消息時 io.open 的第二個返回值,并成為了 assert 的第二個參數(shù)
do
local file, msg
repeat
print("enter a file name:")
local name = io.read()
if not name then
return
end
file = assert(io.open(name, "r"))
until file
end
錯誤處理與異常
大多數(shù)情況無需在,Lua 中作任何錯誤處理,由調用 Lua 的應用程序來負責
因為所有的 Lua 活動都是由應用程序的一次調用而開始的
通常是要求 Lua 執(zhí)行一個程序塊
如果發(fā)生錯誤,此調用就會返回錯誤代碼,并由應用程序處理
在解釋器程序中發(fā)生錯誤時,主循環(huán)會打印錯誤消息,然后繼續(xù)顯示提示符,并等待執(zhí)行后續(xù)命令
在 Lua 中處理錯誤,必須使用 pcall 來包裹要執(zhí)行的代碼, p-->意為 protect 保護的意思
pcall 可以捕獲函數(shù)執(zhí)行時引發(fā)的任何錯誤
如果沒有錯誤,就會返回 true 以及函數(shù)調用的返回值
如果有錯誤,就會返回 false 以及錯誤消息
-- 執(zhí)行一段 Lua 代碼,捕獲所有執(zhí)行中發(fā)生的錯誤,需先將這段代碼封裝到一個函數(shù)中
function foo()
if 未預期的條件 then
error()
end
print(a[i]) -- 潛在的錯誤,a 可能不是一個 table
end
if pcall(foo) then
-- 執(zhí)行 foo 時沒有發(fā)生錯誤
else
-- foo 引發(fā)了一個錯誤,進行錯誤處理
end
調用 pcall 時可以傳入一個匿名函數(shù)
「錯誤消息」可以是任何值,并將其傳遞給 error 函數(shù),這些值也就成為 pcall 的返回值
if pcall (function ()
--
return 20 + 10 -- 用于測試的代碼 "a" + 10
end) then
--
print("ok")
else
--
print("error")
end
do
local status, err = pcall(function ()
error({code = 121})
end)
print(status, err.code)
end
在 Lua 中一個完整異常處理流程通常是:
使用 error 來拋出異常
使用 pcall 來捕獲異常
錯誤消息用來標識錯誤類型或內容
錯誤消息與追溯
錯誤消息通常是一個描述出錯內容的字符串
Lua 遇到一個內部錯誤,如索引一個非 table 的值,就會產生錯誤消息
其他情況下是錯誤消息是傳遞給 error 函數(shù)的值
只要錯誤消息是一個字符串,Lua 就會附加一些錯誤發(fā)生位置的信息
do
local status, err = pcall(function () a ="a"+1 end)
print(err)
end
do
local status, err = pcall(function ()
error("my error")
end)
print(err)
end
-- 位置信息包含文件名 stdin 及行號 3
-- stdin:3: my error
error 函數(shù)的第二個參數(shù) level ,用于指出應有調用層級中的那個(層)函數(shù)來報告當前的錯誤,即誰為錯誤負責
-- 在一個函數(shù)中,一開始就檢查傳入參數(shù)是否正確
do
function foo(str)
if type(str) ~= "string" then
-- 不加第二個參數(shù),則認為是讀函數(shù)時出錯并報告錯誤, stdin:3: string expected
-- error("string expected")
-- 加上第二個參數(shù),則認為是在調用層出錯并報告錯誤, stdin:9: string expected
error("string expected", 2)
end
print(str)
end
foo({x = 1})
end
pcall 函數(shù)返回錯誤消息時,它已經銷毀了調用棧的部分內容
如果要獲取完整的追溯到發(fā)生錯誤時的函數(shù)調用情況,而不是僅僅獲取到錯誤發(fā)生的位置,需要用到 xpcall 函數(shù)
xpcall 函數(shù)接受兩個參數(shù)
需要被調用的函數(shù)
以及一個錯誤處理函數(shù)
發(fā)生錯誤時,Lua 會在調用棧展開前調用錯誤處理函數(shù),就可以用 debug 庫來獲取錯誤的額外信息
debug 庫的兩個通用處理函數(shù)
debug.debug ,提供一個 Lua 提示符,讓用戶檢查錯誤的原因
debug.traceback ,根據調用棧來構建一個擴展的錯誤消息
解釋器程序使用 debug.traceback 來構建其錯誤消息
任何時候調用 debug.traceback 都可以獲取當前執(zhí)行的調用棧
do
local t = {2, 4, 6, 8 ,10}
for i,v in ipairs(t) do
print(i, v)
print(debug.traceback())
end
end
本篇文章由一文多發(fā)平臺ArtiPub自動發(fā)布
總結
以上是生活随笔為你收集整理的lua 收不到服务器发来消息,lua 学习之错误处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 无线服务器软件,关于无线802.1x结合
- 下一篇: 国家电网安装充电桩流程