错误处理

动态链接

在 Lua 中,动态链接被视为所有其他机制的母机制

因此利用它就可以动态地加载任何其他不在 Lua 中的机制

package.loadlib 所需两个参数

库的完整路径

正确的函数名称

loadlib 函数加载指定的库,并将其链接入 Lua

它没有调用库中的任何函数

而是将一个 C 编写的函数作为 Lua 函数返回

如果加载库或查找初始化函数时发生错误,会返回 nil 及一条错误信息

local path = "c:/lua/5.1/socket.so"

local f = package.loadlib(path, "luaopen_socket")

通常使用 require 来加载 C 程序库,这个函数会搜索指定的库

然后用 loadlib 加载库,并返回初始化函数

这个初始化函数应将库中提供的函数注册到 Lua 中,就类似 Lua 代码块中定义了其他函数

错误

Lua 是一种扩展语言,通常嵌入在应用程序中

如果发生错误时如果直接崩溃或退出,那么我们就无法捕获到错误出现在哪里

因此 Lua 只要发生一个错误,就应该结束当前程序块并返回应用程序

Lua 中任何未预期条件都会引发一个错误,如:

将两个非数字的值相加

对一个不是函数的值进行调用操作

索引一个不是 Table 的值

可以通过调用 error 函数,显式地引发发一个错误

需要传入一个错误消息的函数

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 如果第一个参数为 true 则返回该参数

如果第一个参数为 false 或 nil 就会引发一个错误

第二个参数为一个可选的信息字符串

在调用 assert 时会对其参数求值

下述代码中,即使 n 是数字类型, Lua 也会进行字符串连接

n = io.read()

assert(tonumber(n), "invalid input:" .. n .. " is not a number")

当一个函数遭遇了一种未预期的情况即「异常」,可以采取两种基本行为

返回错误代码 (通常是 nil)

引发一个错误(调用 error)

sin 传入 table 作为参数

-- 返回一个错误代码,检查 sin 函数返回值

local res = math.sin(x)

if not res then

end

-- 调用 sin 之前,检查参数

if not tonumber(x) then

end

通常既不检查参数也不会检查 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 第一个参数为文件路径,第二个参数为打开模式,r 为字符模式

-- io.open 成功则返回文件句柄,无法打开会返回 nil 和错误消息

file, msg = io.open(name, "r")

if not file then

print(msg)

end

until file

end

-- 等效于上述代码.错误消息时 io.open 的第二个返回值,并成为了 assert 的第二个参数

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

错误处理与异常

大多数情况无需在,Lua 中作任何错误处理,由调用 Lua 的应用程序来负责

因为所有的 Lua 活动都是由应用程序的一次调用而开始的

通常是要求 Lua 执行一个程序块

如果发生错误,此调用就会返回错误代码,并由应用程序处理

在解释器程序中发生错误时,主循环会打印错误消息,然后继续显示提示符,并等待执行后续命令

在 Lua 中处理错误,必须使用 pcall 来包裹要执行的代码, p-->意为 protect 保护的意思

pcall 可以捕获函数执行时引发的任何错误

如果没有错误,就会返回 true 以及函数调用的返回值

如果有错误,就会返回 false 以及错误消息

-- 执行一段 Lua 代码,捕获所有执行中发生的错误,需先将这段代码封装到一个函数中

function foo()

if 未预期的条件 then

error()

end

print(a[i]) -- 潜在的错误,a 可能不是一个 table

end

if pcall(foo) then

-- 执行 foo 时没有发生错误

else

-- foo 引发了一个错误,进行错误处理

end

调用 pcall 时可以传入一个匿名函数

「错误消息」可以是任何值,并将其传递给 error 函数,这些值也就成为 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 函数的值

只要错误消息是一个字符串,Lua 就会附加一些错误发生位置的信息

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 函数的第二个参数 level ,用于指出应有调用层级中的那个(层)函数来报告当前的错误,即谁为错误负责

-- 在一个函数中,一开始就检查传入参数是否正确

do

function foo(str)

if type(str) ~= "string" then

-- 不加第二个参数,则认为是读函数时出错并报告错误, stdin:3: string expected

-- error("string expected")

-- 加上第二个参数,则认为是在调用层出错并报告错误, stdin:9: string expected

error("string expected", 2)

end

print(str)

end

foo({x = 1})

end

pcall 函数返回错误消息时,它已经销毁了调用栈的部分内容

如果要获取完整的追溯到发生错误时的函数调用情况,而不是仅仅获取到错误发生的位置,需要用到 xpcall 函数

xpcall 函数接受两个参数

需要被调用的函数

以及一个错误处理函数

发生错误时,Lua 会在调用栈展开前调用错误处理函数,就可以用 debug 库来获取错误的额外信息

debug 库的两个通用处理函数

debug.debug ,提供一个 Lua 提示符,让用户检查错误的原因

debug.traceback ,根据调用栈来构建一个扩展的错误消息

解释器程序使用 debug.traceback 来构建其错误消息

任何时候调用 debug.traceback 都可以获取当前执行的调用栈

do

local t = {2, 4, 6, 8 ,10}

for i,v in ipairs(t) do

print(i, v)

print(debug.traceback())

end

end

本篇文章由一文多发平台ArtiPub自动发布

lua 收不到服务器发来消息,lua 学习之错误处理相关推荐

  1. android app后台收不到消息,不打开智能关怀App收不到手表发的消息

    不打开智能关怀App手机收不到手表发的聊天消息.进出安全区域.开关机.视频通话.奖励等消息通知.一般是由于智能关怀App 的后台保护设置及消息通知权限设置未正确设置导致的,以下为常见机型智能关怀App ...

  2. Socket发完消息后,立即关闭连接,客户端丢失数据的问题

    使用.net编写服务器程序的时候,发现一个现象:如果服务器发完消息,立即关闭连接,客户端将无法收到服务器最后发的那条消息.个人猜想,会不会socket也有象文件流类似的缓存机制.果断利用visual ...

  3. telnet给服务器发消息,[摘抄]使用telnet命令直接发送

    需要注意的是,由于现在邮件服务器大多设置了身份验证,禁止非法连接发送邮件,主要是为了防止垃圾邮件的侵袭,所以以下方法不保障能完全成功,贴在这里供大家参考,了解两台邮件服务器之间的对接过程.如果你操作的 ...

  4. 微信小程序接受服务器发过来的消息,微信小程序API 接收消息和事件

    接收消息和事件 当用户在客服会话发送消息.或由某些特定的用户操作引发事件推送时,微信服务器会将消息或事件的数据包发送到开发者填写的 URL,如果使用的是云开发,则可以推送到指定的云函数(详情请参考消息 ...

  5. send函数给FTP服务器发消息,send函数给FTP服务器发消息

    send函数给FTP服务器发消息 内容精选 换一换 Kafka系列2:深入理解Kafka消费者上篇聊了Kafka概况,包含了Kafka的基本概念.设计原理,以及设计核心.本篇单独聊聊Kafka的生产者 ...

  6. JAVA对接公众号(二、处理微信服务器发来的消息)

    一.验证公众号配置的服务器信息. 须知:处理微信服务器发来的消息之前必须先通过公众号配置的服务器验证 获取AccessToken,里面的HttpClientUtil类可以从我csdn资源中找 /*** ...

  7. html怎么直接给服务器发消息,HTML5教程之服务器发送事件

    HTML5 服务器发送事件(Server-Sent Events)允许网页获得来自服务器的更新. Sever-Sent事件 -单项消息传递 Sever-Sent事件指的是网页自动获取来自服务器的更新 ...

  8. centos上搭建nginx视频点播服务器(nginx+vod+lua http发送鉴权消息)

    需求背景: 想着搭建一个视频点播服务器,最后选择了nginx+vod的方案,用lua脚本写拉流鉴权,但是环境搭建过程中又发现nginx++vod+lua的环境并不是很容易搭建,是nginx+lua的环 ...

  9. Java邮件收发,以及获取收件箱和发件箱 自测可用 使用JavaMail

    Java邮件收发,以及获取收件箱和发件箱 自测可用 Java发送邮件 使用javaMail 1.5.6发送邮件 协议smtp smtp地址 smtp.域名 端口SSL 465/994 非SSL25 实 ...

最新文章

  1. 如何在github存储库中添加屏幕截图到README?
  2. Spring Cloud Netflix Zuul中的速率限制
  3. python基础代码事例-零基础学习Python开发练习100题实例(2)
  4. 一个openMP编程处理图像的示例
  5. WebIDE push files to ABAP repository
  6. 离职证明电子版_离职证明中说劳动者因违纪离职的怎么办?
  7. Docker 下载 JDK 镜像(docker search 、docker pull)
  8. Python 核心编程(第二版)——条件和循环
  9. [书目20170308]卓有成效的管理者
  10. mysql 字段值1_2_3 如何查询3是否存在?_MySQL根据col1中的值是否存在于col2中以及col3是否=值来更新col4...
  11. oracle PL/SQL(procedure language/SQL)程序设计(在PL/SQL中使用SQL)
  12. iOS开发之cocoapods安装(2017)
  13. python对八大常见排序算法的总结和实现以及时间消耗分析
  14. 2019最新 Java商城秒杀系统的设计与实战视频教程(SpringBoot版)_1-1课程整体介绍...
  15. 网络信息安全之防火墙入反病毒技术 (七)
  16. php file_get_contents路径问题,file_get_contents与相对路径
  17. VC++ excel 写入与写出数据
  18. 计算机应用大赛动员大会,计算机应用工程系第十二届学生会动员大会
  19. 2021-06-11警告: 多个不同应用注册了相同服务,请检查
  20. 用sdk画三叶玫瑰曲线

热门文章

  1. java学习面向对象之内部类
  2. 2013年1季度中国汽车品牌口碑研究报告 ——自主A级车
  3. new/delete与malloc/free的区别和联系
  4. 是什么管脚分配_FPGA是什么?里面有什么?能做什么?
  5. 用反向传导进行分子动力学模拟并比较NN二甲基苯胺,N甲基苯胺,苯胺,硝基苯的定位效应
  6. python输入输出简单例子_Python 文件和流的简单示例
  7. java非法字符65289_求详细点的回答 谢谢
  8. 第4章-无人车UGV模型分析
  9. RK2908开机时间分析及优化
  10. 人工智能成2020热搜专业,少儿编程未来可期!