避免在 Lua 中使用全局变量并使用特定回调机制

我想要使用一个 Lua API,该 API 在事件发生时具有特定的回调函数,例如当 TCP 包到达时。首先,该函数必须被注册,但需要使用函数名称作为字符串,如下面的示例代码所示

function __init__()
    local dstport = 4681
    local dstIP = "192.168.1.42"
    -- 注册回调函数
    register_tcp_handler('tcp_package_handler', dstIP, dstPort)
end

-- 回调函数
function tcp_package_handler(srcIP, srcPort, dstIP, dstPort, payload)
    -- 检查有效载荷或重置看门狗
end

希望回调函数提供给调用者其他变量,例如看门狗计时器或其他对象。

我能想到的最简单的方法是将 extravariables 设置为全局变量,但我认为这是最不优雅的方式。如果我可以直接传递函数,则闭包会有所帮助,但我不能。我必须使用函数名称作为字符串。

考虑到这个机制,有没有更优雅的方法向回调函数提供变量而不使它们成为全局变量?

编辑:像这样使用闭包

function closure_tcp_package_handler(srcIP, srcPort, dstIP, dstPort, payload, packagecounter, timerobject)
    function tcp_package_handler(srcIP, srcPort, dstIP, dstPort, payload)
        -- 做一些事情,更改 packagecounter,timerobject
    end
    return 'tcp_package_handler'
end

并将此函数使用两次进行注册,例如使用 'packagecounter1,timerobject1' 和 'packagecounter2,timerobject2',只有最后一对参数会被更改。

点赞
用户734069
用户734069

你在处理回调基础架构问题。在这种情况下,你的代码不是调用处理程序的代码。因此,没有办法隐藏那些参数;如果你可以改变它们,那么有访问处理程序所在模块的其他人也可以改变它们。

当然,这并不意味着它们必须是全局的。你可以把它们作为一个表的成员。如果你想确保它们只获取某些参数,甚至可以提供设置器函数来设置参数。

它的简单形式如下:

local handler_params = {}

function tcp_package_handler(srcIP, srcPort, dstIP, dstPort)
    -- 检查 `handler_params.payload`
end

-- 使 `handler_params` 可供外部修改

如何实现最后一个部分完全取决于你。你可以把它变成一个全局的,但如果它在某个模块中,最好将其作为该模块表的成员。同样,如果你想对谁可以访问它以及如何访问它进行一些控制,可以使用设置器函数:

function tcp_handler_set_payload(payload)
  handler_params.payload = payload
end
2018-08-19 18:00:46