Lua - 错误处理

  • 需要错误处理

    错误处理非常重要,因为现实世界的操作通常需要使用复杂的操作,包括文件操作、数据库事务和 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 并产生错误。
  • 断言和错误函数

    为了处理错误,我们经常使用两个函数 - asserterror. 一个简单的例子如下所示。
    
    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])终止最后调用的受保护函数并返回消息作为错误消息。此函数错误永远不会返回。通常,error 在消息的开头添加一些关于错误位置的信息。level 参数指定如何获取错误位置。使用级别 1(默认值),错误位置是调用错误函数的位置。级别 2 将错误指向调用错误的函数的调用位置;等等。传递级别 0 可避免将错误位置信息添加到消息中。
  • pcall 和 xpcall

    在 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
    
    作为程序员,最重要的是确保在编写的程序中进行正确的错误处理。使用错误处理可以确保在不干扰程序用户的情况下处理超出边界条件的意外情况。