紫猫学院社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1553|回复: 5

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

[复制链接]

629

主题

2018

帖子

2038

积分

院长

Rank: 9Rank: 9Rank: 9

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

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

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

x
由于紫猫手机插件代码行数已经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()
回复

使用道具 举报

1

主题

80

帖子

80

积分

按键电脑&手机班学员

QQ 262832680

Rank: 8Rank: 8

猫粮
806
发表于 2018-6-1 18:49:40 | 显示全部楼层
前排支持
回复

使用道具 举报

2

主题

20

帖子

20

积分

Lua第一期学员

Rank: 8Rank: 8

猫粮
540
QQ
发表于 2018-12-28 00:58:32 | 显示全部楼层
好东西,mark
回复

使用道具 举报

0

主题

10

帖子

10

积分

按键手机班学员

Rank: 8Rank: 8

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

使用道具 举报

0

主题

12

帖子

12

积分

学前班

Rank: 1

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

使用道具 举报

5

主题

19

帖子

19

积分

按键电脑&手机班学员

Rank: 8Rank: 8

猫粮
94
发表于 2019-9-17 15:18:48 | 显示全部楼层
过来学习学习!!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2020-6-7 13:50

Powered by Discuz! X3.4

Copyright © 2012-2020 紫猫编程学院

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