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

2023-11-23 12:04

本文主要是介绍【lua】记录函数名和参数(为了延后执行),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

需求背景

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

方案思考

1.临时新建对象

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

2.延后处理

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

方案选择

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

具体代码

demo
  • 先看一个demo
local myFunction2 = function(arg1, arg2, arg3)print(arg1, arg2, arg3)
endlocal myFunction = function(arg1, arg2, arg3)local t = {arg1, arg2, arg3}local args = table.pack(arg1, arg2, arg3)myFunction2(table.unpack(args))
endmyFunction("hello", 42, {a = 2, b = 3})
  • 可以通过 table.pack将参数保存到table里,要使用的时候,再table.unpack使用。
  • 序列化的话,可以用cjson.encode
第一版
-- 导入 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-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" thenmyFunction(unpack(args))  -- 使用 unpack 将参数展开传递给函数
elseprint("Invalid function.")
end

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

其他

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

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

  • 查了一些解决方案,最后使用的是
cjson.encode_sparse_array(true)
  • 使用上面方案之后,unpack(args)又异常了。于是调整代码。
local serializedData = cjson.encode({func = myFunction, args = {arg1, arg2, arg3})-- ... 此处省略中间过程local data = cjson.decode(serializedData)
if data.func and self[data.func] thenlocal 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函数参数一般不会有这么多,实在超了,只能再加了。

这篇关于【lua】记录函数名和参数(为了延后执行)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/417829

相关文章

Python获取中国节假日数据记录入JSON文件

《Python获取中国节假日数据记录入JSON文件》项目系统内置的日历应用为了提升用户体验,特别设置了在调休日期显示“休”的UI图标功能,那么问题是这些调休数据从哪里来呢?我尝试一种更为智能的方法:P... 目录节假日数据获取存入jsON文件节假日数据读取封装完整代码项目系统内置的日历应用为了提升用户体验,

Kotlin 作用域函数apply、let、run、with、also使用指南

《Kotlin作用域函数apply、let、run、with、also使用指南》在Kotlin开发中,作用域函数(ScopeFunctions)是一组能让代码更简洁、更函数式的高阶函数,本文将... 目录一、引言:为什么需要作用域函数?二、作用域函China编程数详解1. apply:对象配置的 “流式构建器”最

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio

MySQL INSERT语句实现当记录不存在时插入的几种方法

《MySQLINSERT语句实现当记录不存在时插入的几种方法》MySQL的INSERT语句是用于向数据库表中插入新记录的关键命令,下面:本文主要介绍MySQLINSERT语句实现当记录不存在时... 目录使用 INSERT IGNORE使用 ON DUPLICATE KEY UPDATE使用 REPLACE

Python 中的异步与同步深度解析(实践记录)

《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

Spring定时任务只执行一次的原因分析与解决方案

《Spring定时任务只执行一次的原因分析与解决方案》在使用Spring的@Scheduled定时任务时,你是否遇到过任务只执行一次,后续不再触发的情况?这种情况可能由多种原因导致,如未启用调度、线程... 目录1. 问题背景2. Spring定时任务的基本用法3. 为什么定时任务只执行一次?3.1 未启用

Android Kotlin 高阶函数详解及其在协程中的应用小结

《AndroidKotlin高阶函数详解及其在协程中的应用小结》高阶函数是Kotlin中的一个重要特性,它能够将函数作为一等公民(First-ClassCitizen),使得代码更加简洁、灵活和可... 目录1. 引言2. 什么是高阶函数?3. 高阶函数的基础用法3.1 传递函数作为参数3.2 Lambda

一文带你了解SpringBoot中启动参数的各种用法

《一文带你了解SpringBoot中启动参数的各种用法》在使用SpringBoot开发应用时,我们通常需要根据不同的环境或特定需求调整启动参数,那么,SpringBoot提供了哪些方式来配置这些启动参... 目录一、启动参数的常见传递方式二、通过命令行参数传递启动参数三、使用 application.pro

redis+lua实现分布式限流的示例

《redis+lua实现分布式限流的示例》本文主要介绍了redis+lua实现分布式限流的示例,可以实现复杂的限流逻辑,如滑动窗口限流,并且避免了多步操作导致的并发问题,具有一定的参考价值,感兴趣的可... 目录为什么使用Redis+Lua实现分布式限流使用ZSET也可以实现限流,为什么选择lua的方式实现