【lua】记录函数名和参数(为了延后执行)

需求背景

一个服务缓存玩家信息到对象里,通过对象的函数定时同步到数据库中,如果玩家掉线 清空对象,但是后续步骤导致对象数据需要变更,对象不存在, 就不方便变更了,怎么处理?

方案思考

1.临时新建对象

既然更新数据依赖对象,判断对象不存在的时候,先新建对象,再使用对象操作。

2.延后处理

判断对象不存在的时候,先记录函数名和参数,等对象下次出现的时候,延后调用。

方案选择

因为项目中使用的对象涉及到网络,玩家掉线情况下,参数不全,无法新建对象,所以选延后处理的方案比较合适。

具体代码

demo
  • 先看一个demo
lua 复制代码
local myFunction2 = function(arg1, arg2, arg3)
    print(arg1, arg2, arg3)
end


local myFunction = function(arg1, arg2, arg3)
    local t = {arg1, arg2, arg3}
    local args = table.pack(arg1, arg2, arg3)
    myFunction2(table.unpack(args))
end

myFunction("hello", 42, {a = 2, b = 3})
  • 可以通过 table.pack将参数保存到table里,要使用的时候,再table.unpack使用。
  • 序列化的话,可以用cjson.encode
第一版
lua 复制代码
-- 导入 lua-cjson 库
local cjson = require("cjson")

-- 定义一个要序列化的函数
local myFunction = function(arg1, arg2, arg3)
    print(arg1, arg2, arg3)
end

-- 定义函数的参数
local args = {1, "hello", {a = 2, b = 3}}

-- 序列化函数和参数
local serializedData = cjson.encode({func = myFunction, args = args})

-- 打印序列化后的数据
print(serializedData)
lua 复制代码
-- 导入 lua-cjson 库
local cjson = require("cjson")

-- 被序列化的数据
local serializedData = '{"func":null,"args":[1,"hello",{"a":2,"b":3}]}'

-- 反序列化数据
local data = cjson.decode(serializedData)

-- 获取函数和参数
local myFunction = data.func
local args = data.args

-- 执行函数
if type(myFunction) == "function" then
    myFunction(unpack(args))  -- 使用 unpack 将参数展开传递给函数
else
    print("Invalid function.")
end

序列化之后可以存入redis,我这里使用的是redis的list。

其他

  • 实际使用过程中碰到一些问题,比如 cjson.encode 的时候报错 Cannot serialise table: excessively sparse array,原因是实际业务的args过于复杂。

这个错误通常发生在你尝试使用 cjson.encode 函数序列化一个 Lua 表时,而这个表包含了"过于稀疏"的数组部分。所谓"过于稀疏"是指数组中存在很多 nil 元素,而 cjson 在序列化时对这样的数组处理有一些限制。

  • 查了一些解决方案,最后使用的是
lua 复制代码
cjson.encode_sparse_array(true)
  • 使用上面方案之后,unpack(args)又异常了。于是调整代码。
lua 复制代码
local serializedData = cjson.encode({func = myFunction, args = {arg1, arg2, arg3})


-- ... 此处省略中间过程


local data = cjson.decode(serializedData)
if data.func and self[data.func] then
   local args = data.args or {}
       self[data.func](self, args[1], args[2], args[3], args[4], args[5], args[6], args[7])
   end
end
  • 因为是通用方案,所以参数支持到7位,一般lua函数参数一般不会有这么多,实在超了,只能再加了。
相关推荐
bzmK1DTbd6 小时前
Git版本控制:Java项目中的分支管理与合并策略
java·开发语言·git
Rust研习社6 小时前
为什么 Rust 没有空指针?
开发语言·后端·rust
kyriewen116 小时前
WebAssembly:前端界的“外挂”,让C++代码在浏览器里跑起来
开发语言·前端·javascript·c++·单元测试·ecmascript
其实防守也摸鱼8 小时前
CTF密码学综合教学指南--第九章
开发语言·网络·python·安全·网络安全·密码学·ctf
砚底藏山河8 小时前
Python量化开发:2026最佳实时股票数据API接口推荐与对比
开发语言·windows·python
AlunYegeer9 小时前
JAVA,以后端的视角理解前端。在全栈的路上迈出第一步。
java·开发语言·前端
hixiong12310 小时前
C# OpenvinoSharp使用DINOv2模型进行图像相似度计算
开发语言·c#
DFT计算杂谈10 小时前
自动化脚本一键绘制三元化合物相图
java·运维·服务器·开发语言·前端·python·自动化
EW Frontier11 小时前
6G ISAC新范式:基于智能漏波天线的Wi‑Fi通感一体化系统设计与实测【附MATLAB+python代码】
开发语言·python·matlab·music·isac·doa·wi‑fi
楼田莉子11 小时前
Linux网络:NAT_代理
linux·运维·服务器·开发语言·c++·后端