【奇怪的bug】lua的nil不报错
故事背景,因为需求变更,战斗之前的代码从logic移动到了场景,出现卡战斗的情况。调试发现很多奇怪的问题。进了lua函数但是没有出函数,又看不到任何报错。最后发现其实就是nil后lua没报错。nil为何没报错没找到,但是用pcall可以捕获报错。
还有一个问题,我们伤害公式是写在配置的是,需要转换成函数,为了性能,其实是加载的时候就完成了转换,不用每次使用公式都去解析配置。但是问题出现了,如果提前解析居然找不到配置问题。思前想后加载做了容错处理,在使用的时候如果没初始化再初始化一次,
有空再回头去看看为何配置文件加载出现了延迟。
这是代码
--根据敏捷出手
local function sortSpeed(battleCards)print("------------sortSpeed------start-----------")local cards = {}print("------------sortSpeed------11111111111-----------")for _,card in pairs(battleCards)dotable.insert(cards, card)endprint("------------sortSpeed------222222222222222-----------")table.sort(cards,function(a,b) return a.attributes[bt_const.Property.SHARP] > b.attributes[bt_const.Property.SHARP] end)--print("-----cards-------",tostring(cards.attributes))print("-------------sortSpeed------end-----------------")return cards
end
这是运行输出
--------processBattleRound------------start
--------processBattleRound------------111111111111
------------sortSpeed------start-----------
------------sortSpeed------11111111111-----------
------------sortSpeed------222222222222222-----------
为什么 不输出 --sortSpeed------end-
正确的代码
local function sortSpeed(battleCards)print("------------sortSpeed------start-----------")local cards = {}print("------------sortSpeed------11111111111-----------")for _,card in pairs(battleCards)dotable.insert(cards, card)endprint("------------sortSpeed------222222222222222-----------")-- 添加错误处理local success, err = pcall(function()table.sort(cards, function(a,b) return a.attributes[bt_const.Property.SHARP] > b.attributes[bt_const.Property.SHARP] end)end)if not success thenprint("排序错误:", err)-- 可以在这里添加备用的排序逻辑endprint("-------------sortSpeed------end-----------------")return cards
end
这一行有报错 table.sort(cards,function(a,b) return a.attributes[bt_const.Property.SHARP] > b.attributes[bt_const.Property.SHARP] end)。但是不pcall居然不打印
function formulas.Init()local success, err = pcall(function()print("开始初始化公式系统...")-- 初始化formulas_list,确保不为nilformulas_list = formulas_list or {}-- 检查配置是否存在if not cfg_query thenerror("cfg_query 为 nil")elseif not cfg_query.formulas thenerror("cfg_query.formulas 为 nil")elseif type(cfg_query.formulas) ~= "table" thenerror("cfg_query.formulas 不是table,实际类型: " .. type(cfg_query.formulas))endlocal formulaCount = 0local successCount = 0for id, config in pairs(cfg_query.formulas) doformulaCount = formulaCount + 1if not config thenprint("警告: 公式配置为nil, id:", id)elseif not config.formula thenprint("警告: 公式配置缺少formula字段, id:", id)elselocal compileSuccess, result = pcall(loadFormula, config.formula)if compileSuccess thenformulas_list[id] = resultsuccessCount = successCount + 1elseprint("错误: 编译公式失败, id:", id, "错误:", result)endendendprint(string.format("公式加载完成: 总计%d个, 成功%d个", formulaCount, successCount))-- 测试所有公式print("开始测试公式...")local testFormulas = {{100001, "基础伤害-攻击力"},{100002, "伤害/攻击治疗暴击率计算公式"},{100003, "命中公式"},{100004, "效果命中公式"},{100005, "治疗公式-以我方最大生命治疗"},{100006, "治疗公式-以我方攻击治疗"},{100007, "护盾公式-生命护盾"},{100008, "护盾公式-防御护盾"},{100009, "基础伤害-真实伤害"}}for _, test in ipairs(testFormulas) dolocal id, name = test[1], test[2]if formulas_list[id] thenlocal testSuccess, testErr = pcall(testFormula, id, name)if not testSuccess thenprint(string.format("测试公式%d(%s)失败: %s", id, name, testErr))endelseprint(string.format("警告: 公式%d(%s)不存在,跳过测试", id, name))endendprint("\n===== 公式初始化完成 =====")end)if not success thenprint("公式初始化失败:", err)-- 初始化空表,避免后续使用出错formulas_list = formulas_list or {}return falseendreturn true
end
--延迟一秒等待配置加载
skynet.timeout(1, function()formulas.Init()
end)game[system][09-26 08:56:31][s:0001][logger.lua:222][f:001f]: LAUNCH snlua game_svc 19 2 1
开始初始化公式系统...
game[fatal][09-26 08:56:31][s:001f][cfg_query.lua:20]sharedata.query faild no found cfg file:formulas err:../depends/skynet/lualib/skynet.lua:143: dest address type (nil) must be a string or number.
公式初始化失败: ../common/lualib/cfg_query.lua:21: assertion failed!
game[info][09-26 08:56:31][s:001f][redis_conn.lua:25]redis connect svc_name:game_svc id:1
game[info][09-26 08:56:31][s:001f][redis_conn.lua:31]redis connected host:127.0.0.1 port:6379 db:1 auth:zjy0822
-------initMap--------------- 1
---send_msg- 61 nil nil true Scene.NtEnterScene
---send_msg- 61 nil nil true Mate.NtGameRoom
--------router_helper.Scene------------- EnterSceneReq
gate[info][09-26 08:56:31][s:001e][proxy.lua:20]load cluster_node node_name:game node:game
game[info][09-26 08:56:31][s:001f][proxy.lua:20]load cluster_node node_name:gate node:gate
---send_msg- 61 nil nil true Chapter.NtEventList
game[info][09-26 08:56:31][s:001f][proxy.lua:20]load cluster_node node_name:global node:global
---send_msg- 61 nil nil true Chapter.NtBag
---send_msg- 61 nil nil true Chapter.NtBag
---send_msg- 61 850954111 Scene.EnterSceneReq true Scene.EnterSceneRes
---send_msg- 61 nil nil true Chapter.NtBag
---send_msg- 61 nil nil true Scene.NtNewMember
game[info][09-26 08:56:31][s:0001][proxy.lua:20]load cluster_node node_name:tlog node:tlog
game[system][09-26 08:56:31][s:0001][logger.lua:222][f:0020]: LAUNCH snlua clustersender tlog DESKTOP-D7PF44I2744 127.0.0.1 24025
game[system][09-26 08:56:31][s:0001][logger.lua:222][f:0020]: [sender:tlog] create_channel 127.0.0.1:24025
game[system][09-26 08:56:31][s:0001][logger.lua:222][f:0020]: [sender:tlog] channel not found, need to wait
game[system][09-26 08:56:31][s:0001][logger.lua:222][f:0020]: socket: connect to 127.0.0.1 24025
tlog[system][09-26 08:56:31][s:0001][logger.lua:222][f:0010]: socket accept from 127.0.0.1:15742
game[system][09-26 08:56:31][s:0001][logger.lua:222][f:0020]: [sender:tlog] create_channel 127.0.0.1:24025 success
game[system][09-26 08:56:31][s:0001][logger.lua:222][f:0020]: [sender:tlog] remove_wait 1
tlog[system][09-26 08:56:31][s:0001][logger.lua:222][f:0020]: LAUNCH snlua clusteragent 16 18 37
---send_msg- 61 nil nil true Bag.NtChapterBag
---send_msg- 61 1655486343 Bag.GetItemListReq true Bag.GetItemListRes
---send_msg- 61 1842616733 Equip.GetEquipListReq true Equip.GetEquipListRes
---send_msg- 61 1402488822 Martial.GetMartialListReq true Martial.GetMartialListRes
---send_msg- 61 591114348 Task.GetTaskReq true Task.GetTaskRes
----------EventReq------ 10000100000002 {["cell_id"] = 69,
}
---send_msg- 61 nil nil true Chapter.NtBag
---send_msg- 61 1226136838 Chapter.EventReq true Chapter.EventRes
--------router_helper.Scene------------- NpcDialogReq
-------NpcDialogReq------- {["event_id"] = 2,["choose"] = 0,
}
------NpcDialogRes----- {["event_id"] = 2,["dialog_id"] = -1,
}
---send_msg- 61 1679503000 Scene.NpcDialogReq true Scene.NpcDialogRes
--------router_helper.Scene------------- MoveActionReq
---send_msg- 61 661480200 Scene.MoveActionReq true Scene.MoveActionRes
----------EventReq------ 10000100000002 {["cell_id"] = 76,
}
---send_msg- 61 nil nil true Chapter.NtBag
---send_msg- 61 1755804238 Chapter.EventReq true Chapter.EventRes
--------router_helper.Battle------------- BattleCreateReq
开始初始化公式系统...
公式加载完成: 总计9个, 成功9个
开始测试公式...
=== 测试公式 100001: 基础伤害-攻击力 ===
计算结果: 1323.60
测试通过 ✓
=== 测试公式 100002: 伤害/攻击治疗暴击率计算公式 ===
计算结果: 0.20
测试通过 ✓
=== 测试公式 100003: 命中公式 ===
计算结果: 0.80
测试通过 ✓
=== 测试公式 100004: 效果命中公式 ===
计算结果: 0.55
测试通过 ✓
=== 测试公式 100005: 治疗公式-以我方最大生命治疗 ===
计算结果: 18120.00
测试通过 ✓
=== 测试公式 100006: 治疗公式-以我方攻击治疗 ===
计算结果: 2880.00
测试通过 ✓
=== 测试公式 100007: 护盾公式-生命护盾 ===
计算结果: 15100.00
测试通过 ✓
=== 测试公式 100008: 护盾公式-防御护盾 ===
计算结果: 850.00
测试通过 ✓
=== 测试公式 100009: 基础伤害-真实伤害 ===
计算结果: 0.00
测试通过 ✓
===== 公式初始化完成 =====
最开始是延时加载公式,发现然并卵,自己在使用的时候判断再加载的。会出现创建场景加载失败,然后创建战斗的时候又加载成功,。,。。
--如果公式没加载,加载一次if(not g_data.formulas_list[100001])thenformulas.Init()end