找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 8557|回复: 6

[教程源码] [lua]在Lua中实现try...catch...finally功能

[复制链接]
  • 打卡等级:武林至尊

1087

主题

2143

回帖

4337

积分

院长

鲜花
9
猫粮
7517
QQ
发表于 2018-6-1 17:57:31 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
由于紫猫手机插件代码行数已经6800多行了, 打算重构下, 故整理了本篇教程.

在lua中, 可以使用pcall或xpcall保护模式执行代码, error抛出异常, 所以利用这些特性来实现try...catch...finally功能

普通写法
[Lua] 纯文本查看 复制代码
function cc(a, b)
    -- try
    local ok, errors = pcall(
        function ()
            return a + b
        end
    )
    
    -- catch
    if not ok then
        print("错误信息:", errors)
    end
    
    -- finally
    print("必定执行的内容")
    
    if ok then
        return errors
    else
        return nil
    end
end

print(cc(1, nil))
print(cc(1, 2))


封装后的写法
[Lua] 纯文本查看 复制代码
local function try(block)
    local tablejoin = function (...)
        local result = {}
        for _, t in ipairs({...}) do
            if type(t) == "table" then
                for k, v in pairs(t) do
                    if type(k) == "number" then table.insert(result, v)
                    else result[k] = v end
                end
            else
                table.insert(result, t)
            end
        end
        return result
    end

    -- get the try function
    local try = block[1]
    assert(try)
    
    -- get catch and finally functions
    local funcs = tablejoin(block[2] or {}, block[3] or {})
    
    -- try to call it
    local result_error = {}
    local results = {pcall(try)}
    if not results[1] then
        -- run the catch function
        if funcs and funcs.catch then
            result_error = {funcs.catch(results[2])}
        end
    end

    -- run the finally function
    if funcs and funcs.finally then
        local result_fin = {funcs.finally(table.unpack(results))}
        if #result_fin > 0 then
            return table.unpack(result_fin)
        end
    end

    -- ok?
    if results[1] and #results > 1 then
        return table.unpack(results, 2, #results)
    else
        if #result_error > 0 then
            return table.unpack(result_error)
        else
            return nil
        end
    end
end

local function catch(block)
    -- get the catch block function
    return {catch = block[1]}
end

local function finally(block)
    -- get the finally block function
    return {finally = block[1]}
end

function bb()
    return try
    {
        -- try 代码块
        function ()
            error("出错了")
        end,

        -- catch 代码块
        catch 
        {
            -- 发生异常后,被执行
            function (errors)
                print("执行bb()错误:", errors)
            end
        },

        -- finally 代码块
        finally 
        {
            -- 最后都会执行到这里
            function (ok, errors)
                -- 如果try{}中存在异常,ok为true,errors为错误信息,否则为false,errors为try中的返回值
                print("必定执行内容:", ok, errors)
            end
        }
    }
end

bb()
楼主热帖
  • 打卡等级:英雄豪杰

3

主题

112

回帖

118

积分

按键电脑&手机班学员

QQ 262832680

鲜花
0
猫粮
3669
发表于 2018-6-1 18:49:40 | 显示全部楼层
前排支持
  • 打卡等级:无名新人

2

主题

19

回帖

23

积分

Lua插件编程班学员

鲜花
0
猫粮
650
QQ
发表于 2018-12-28 00:58:32 | 显示全部楼层
好东西,mark

0

主题

10

回帖

10

积分

按键手机班学员

鲜花
0
猫粮
64
发表于 2019-7-16 14:28:48 | 显示全部楼层
这个对我来说还是太难了

0

主题

12

回帖

12

积分

学前班

鲜花
0
猫粮
8
发表于 2019-7-29 11:58:42 | 显示全部楼层
很给力,学习学习感谢作者

7

主题

16

回帖

30

积分

按键电脑&手机班学员

鲜花
0
猫粮
132
发表于 2019-9-17 15:18:48 | 显示全部楼层
过来学习学习!!!

5

主题

77

回帖

82

积分

小学生

鲜花
0
猫粮
45
发表于 2020-9-30 10:54:17 | 显示全部楼层
前排支持
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|紫猫编程学园

GMT+8, 2024-12-22 23:47

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表