错误

简介: 错误

人人皆难免犯错误。因此,我们必须尽可能地处理错误。由于 Lua 语言是一种经常被嵌入在应用程序中的扩展语言,所以当程序发生时并不能简单地崩溃或退出。相反,只要错误发生, Lua 语言就必须提供处理错误的方式。


Lua 语言会在遇到非预期的情况时引发错误。例如,当试图将两个非数值类型的值相加,对不是函数的值进行调用,对不是表类型的值进行索引等。我们也可以显式地通过调用函数 error 并传入一个错误信息作为参数来引发一个错误。通常,这个函数就是在代码中提示出错的合理方式:

print "enter a number"
n = io.read("n")
if not n then error("invalid input") end


由于“针对某些情况调用函数error”这样的代码结构太常见了,所以 Lua 语言提供了一个内建的函数 assert 来完成这类工作:

print "enter a number"
n = assert(io.read("*n"), "invalid input")


函数 assert 检查其第一个参数是否为真,如果该函数为真则返回该参数;如果该参数为假则引发一个错误。该函数的第 2 个参数是一个可选的错误信息。不过,要注意函数 assert 只是一个普通函数,所以 Lua 语言总是在调用该函数前先对参数进行求值。

如果编写形如:

n = io.read()
assert(tonumber(n), "invalid input" .. n .. " is not a number")


的代码,那么即使 n 是一个数值类型, Lua 语言也总是会进行字符串连接。在这种情况下使用显式的测试可能更加明智。


当一个函数发现某种意外的情况发生时(即异常exception ),在进行异常处理时可以采用两种基本方式:

  1. 返回错误代码(通常是nil或者false
  2. 通过调用函数error引发一个错误。


如何在这两种方式之间进行选择并没有固定的规则,但是按照编码规范(自定的),通常遵循如下的指导原则:


容易避免的异常应该引发错误,否则应该返回错误码。


以函数 math.sin 为例,当调用时参数传入了一个表该如何反应呢?如果要检查错误,那么就不得不编写如下的代码:

local res = math.sin(x)
if not res then             -- 错误?
  -- error-handling code


当然,也可以调用函数前轻松地检查出这种异常:

if not tonumber(x) then       -- x 是否为数字:
  -- error-handling code


通常,我们既不会检查参数也不会检查函数 sin 的返回值;如果 sin 的参数不是一个数值,那么就意味着我们的程序可能出现了问题。此时,处理异常最简单也是最实用的做法就是停止运行,然后输出一条错误信息。


另一方面,让我们再考虑以下用于打开文件的函数 io.open 。如果要打开的文件不存在,那么该函数应该有怎样的行为呢?在这种情况下,没有什么简单的方法可以在调用函数前检测到这种异常。在很多系统中,判断一个文件是否存在的唯一方法就是试着取打开这个文件。因此,如果由于外部原因(比如“文件不存在(file does not exist)”或“权限不足(permission denied)”)导致函数 io.open 无法打开一个文件,那么它应返回 false 及一条错误信息。通过这种方式,我们就有机会采取恰当的方式来处理异常情况,例如要求用户提供另一个文件名:

local file, msg
repeat
  print "enter a file name"
  local name = io.read()
  if not name then return end   -- 没有输入
  file, msg = io.open(name, "r")
  if not file then print(msg) end
util file


如果不想处理这些情况,但又想安全地运行程序,那么只需要使用 assert

file = assert(io.open(name, "r"))   --> stdin:1: no-file: No such file or directory点击复制复制失败已复制


这是 Lua 语言中一种典型的技巧:如果函数 io.open 执行失败, assert 就引发阿一个错误。

目录
相关文章
|
6月前
被零除的错误
被零除的错误。
55 1
|
9月前
|
SQL 数据库 流计算
出现了 FlinkServerException 或 FlinkSQLException 错误
出现了 FlinkServerException 或 FlinkSQLException 错误
277 1
PCLint9可以发现 VS2005不能发现的错误
PCLint9可以发现 VS2005不能发现的错误
|
10月前
|
索引
SpringdataElasticsearch整合时遇到的一个错误
SpringdataElasticsearch整合时遇到的一个错误
57 0
|
11月前
|
弹性计算 应用服务中间件 Apache
502 错误
502 错误
695 0
|
异构计算
之前代码出现的错误总结
之前代码出现的错误总结
78 0
本人使用abapgit遇到的一些错误
本人使用abapgit遇到的一些错误
|
应用服务中间件 PHP nginx

热门文章

最新文章