Lua 是一个扩展性语言, 通常嵌入在其他程序中使用.
所以当Lua运行错误时, 不建议简单的crash或退出, 最好是能返回错误代码和错误信息.
当lua运行时遇到某些错误会抛出异常, 例如对非数字进行数学运算, 调用不存在的函数, 使用不存在的索引取表的值. 通过metatable可以自定义这些错误.
除了这些常见的错误, 我们还可以在lua程序中使用error函数人为的产生错误.
例如, 当条件满足时, 使用error抛出异常 :
> f = io.open("/root/test1.lua","w")
> f:write([[ print("enter a number:")
>> n = io.read("*n")
>> if not n then error("invalid number") end
>> print(n)
>> ]])
> f:close()
> dofile("/root/test1.lua")
enter a number:
9
9
> dofile("/root/test1.lua")
enter a number:
abc
/root/test1.lua:3: invalid number
stack traceback:
[C]: in function 'error'
/root/test1.lua:3: in main chunk
[C]: in function 'dofile'
stdin:1: in main chunk
[C]: in ?
后面一直报错, 不知道是不是BUG
> dofile("/root/test1.lua")
enter a number:
/root/test1.lua:3: invalid number
stack traceback:
[C]: in function 'error'
/root/test1.lua:3: in main chunk
[C]: in function 'dofile'
stdin:1: in main chunk
[C]: in ?
使用assert也能达到同样的效果, 评估第一个参数(io.read("*n"))的返回值, 如果是false 则抛出异常, 并且输出第二个参数作为错误消息.
io.read("*n") , 如果输入不是数字, 返回nil.
> n = assert(io.read("*n"), "invalid number")
99
> print(n)
99
> n = assert(io.read("*n"), "invalid number")
abc
stdin:1: invalid number
stack traceback:
[C]: in function 'assert'
stdin:1: in main chunk
[C]: in ?
> print(n)
99
> n = assert(io.read("*n"), "invalid number")
stdin:1: invalid number
stack traceback:
[C]: in function 'assert'
stdin:1: in main chunk
[C]: in ?
> n = io.read("*l")
ab he
> print(n)
ab he
> n = io.read("*n")
ab12c2d
> print(n)
nil
> n = io.read("*n")
123 3
> print(n)
123
数字判断的例子还可以这么写, 使用 assert 来判断tonumber(n)是否返回nil, 返回nil报错.
n = io.read()
assert(tonumber(n), "invalid input:" .. n .. " is not a number")
注意assert在执行前, 先执行参数中所有的表达式, 所以不管n是否为数字, 都会执行这个字符串连接."invalid input:" .. n .. " is not a number"
文件操作的用法 :
file = assert(io.open(filename, $fmt))
一般用r模式打开文件来判断文件是否存在.
[参考]
1.
error (message [, level])
Terminates the last protected function called and returns message
as the error message. Function error
never returns.
Usually, error
adds some information about the error position at the beginning of the message, if the message is a string. The level
argument specifies how to get the error position. With level 1 (the default), the error position is where the error
function was called. Level 2 points the error to where the function that called error
was called; and so on. Passing a level 0 avoids the addition of error position information to the message.
2.
assert (v [, message])
Issues an error when the value of its argument v
is false (i.e., nil or false); otherwise, returns all its arguments. message
is an error message; when absent, it defaults to "assertion failed!"
3.
io.read (···)
Equivalent to io.input():read(···)
.
- "
*n
": reads a number; this is the only format that returns a number instead of a string. - "
*a
": reads the whole file, starting at the current position. On end of file, it returns the empty string. - "
*l
": reads the next line skipping the end of line, returning nil on end of file. This is the default format. - "
*L
": reads the next line keeping the end of line (if present), returning nil on end of file. - number: reads a string with up to this number of bytes, returning nil on end of file. If number is zero, it reads nothing and returns an empty string, or nil on end of file.