title: 记一个pairs迭代器的坑
date: 2024-06-25 09:48:14
tags: [Lua, 踩坑]
categories: [工作经验]

cover: https://claudia.abril.com.br/wp-content/uploads/2018/06/thinkstockphotos-97731231.jpg

0/碎碎念

由于目前的项目采用的战利品掉落被我设计成每个地图都不一样,之前的功能已经做了每个地图对应的战利品表了,处于方便维护的考虑,这次新增的战利品表也要每个地图都做一个.但是每个表涉及的战利品都非常的多,所以我就想先把所有的表用字符串输出出来再手动复制过去,毕竟这些表只有概率字段是会变的.

1/第一次尝试

所以我就写了下面这个代码来生成每层的表

local format = [[
    [3] = {
        {ItemKey="nil", Num = 1, Bind = 1, Rand={BASE}},
        {ItemKey="物品1", Num = 1, Bind = 1, Rand={RAND1}},
        {ItemKey="物品2", Num = 1, Bind = 1, Rand={RAND2}},
        {ItemKey="物品3", Num = 1, Bind = 1, Rand={RAND3}},
        {ItemKey="物品4", Num = 1, Bind = 1, Rand={RAND4}},
        {ItemKey="物品5", Num = 1, Bind = 1, Rand={RAND5}},
        {ItemKey="物品6", Num = 1, Bind = 1, Rand={RAND6}},
        {ItemKey="物品7", Num = 3, Bind = 1, Rand={RAND7}},
        {ItemKey="物品8", Num = 1, Bind = 1, Rand={RAND8}},
        {ItemKey="物品9", Num = 3, Bind = 1, Rand={RAND9}},
        {ItemKey="物品10", Num = 5, Bind = 1, Rand={RAND10}},
        {ItemKey="物品11", Num = 1, Bind = 1, Rand={RAND11}},
    }
]]

local baseRand = 5000

local otherRand = {
    30,40,90,40,25,25,90,90,40,25,5
}

for i = 1, 36 do
    if i ~= 1 then
        baseRand = baseRand - 11
        for index, value in ipairs(otherRand) do
            value = value + 1
        end
    end
    local tmpStr = string.gsub(format, "{BASE}", baseRand)
    for index, value in ipairs(otherRand) do
        tmpStr = string.gsub(tmpStr, "{RAND"..tostring(index).."}", value)
    end
    print(tmpStr)
end

然而得到的运行结果却是这样的

[3] = {
        {ItemKey="nil", Num = 1, Bind = 1, Rand=5000},
        {ItemKey="物品1", Num = 1, Bind = 1, Rand=30},
        {ItemKey="物品2", Num = 1, Bind = 1, Rand=40},
        {ItemKey="物品3", Num = 1, Bind = 1, Rand=90},
        {ItemKey="物品4", Num = 1, Bind = 1, Rand=40},
        {ItemKey="物品5", Num = 1, Bind = 1, Rand=25},
        {ItemKey="物品6", Num = 1, Bind = 1, Rand=25},
        {ItemKey="物品7", Num = 3, Bind = 1, Rand=90},
        {ItemKey="物品8", Num = 1, Bind = 1, Rand=90},
        {ItemKey="物品9", Num = 3, Bind = 1, Rand=40},
        {ItemKey="物品10", Num = 5, Bind = 1, Rand=25},
        {ItemKey="物品11", Num = 1, Bind = 1, Rand=5},
    }

        [3] = {
        {ItemKey="nil", Num = 1, Bind = 1, Rand=4989},
        {ItemKey="物品1", Num = 1, Bind = 1, Rand=30},
        {ItemKey="物品2", Num = 1, Bind = 1, Rand=40},
        {ItemKey="物品3", Num = 1, Bind = 1, Rand=90},
        {ItemKey="物品4", Num = 1, Bind = 1, Rand=40},
        {ItemKey="物品5", Num = 1, Bind = 1, Rand=25},
        {ItemKey="物品6", Num = 1, Bind = 1, Rand=25},
        {ItemKey="物品7", Num = 3, Bind = 1, Rand=90},
        {ItemKey="物品8", Num = 1, Bind = 1, Rand=90},
        {ItemKey="物品9", Num = 3, Bind = 1, Rand=40},
        {ItemKey="物品10", Num = 5, Bind = 1, Rand=25},
        {ItemKey="物品11", Num = 1, Bind = 1, Rand=5},
    }
    <...>
        [3] = {
        {ItemKey="nil", Num = 1, Bind = 1, Rand=4615},
        {ItemKey="物品1", Num = 1, Bind = 1, Rand=30},
        {ItemKey="物品2", Num = 1, Bind = 1, Rand=40},
        {ItemKey="物品3", Num = 1, Bind = 1, Rand=90},
        {ItemKey="物品4", Num = 1, Bind = 1, Rand=40},
        {ItemKey="物品5", Num = 1, Bind = 1, Rand=25},
        {ItemKey="物品6", Num = 1, Bind = 1, Rand=25},
        {ItemKey="物品7", Num = 3, Bind = 1, Rand=90},
        {ItemKey="物品8", Num = 1, Bind = 1, Rand=90},
        {ItemKey="物品9", Num = 3, Bind = 1, Rand=40},
        {ItemKey="物品10", Num = 5, Bind = 1, Rand=25},
        {ItemKey="物品11", Num = 1, Bind = 1, Rand=5},
    }

可以看到除了第一个nil物品的概率发生了改变,其他的都没有变化.翻来覆去看了5分钟,发现问题出在这里

for index, value in ipairs(otherRand) do
    value = value + 1
end

这里我直接修改了迭代器返回的对象,但是调试的过程中发现,indexvalue都只是迭代器返回的一个值,而不是对表中元素的引用,所以这里的修改并不会改变表中的值.

2/第二次尝试

修改成以下代码就可以了

local format = [[
    [3] = {
        {ItemKey="nil", Num = 1, Bind = 1, Rand={BASE}},
        {ItemKey="物品1", Num = 1, Bind = 1, Rand={RAND1}},
        {ItemKey="物品2", Num = 1, Bind = 1, Rand={RAND2}},
        {ItemKey="物品3", Num = 1, Bind = 1, Rand={RAND3}},
        {ItemKey="物品4", Num = 1, Bind = 1, Rand={RAND4}},
        {ItemKey="物品5", Num = 1, Bind = 1, Rand={RAND5}},
        {ItemKey="物品6", Num = 1, Bind = 1, Rand={RAND6}},
        {ItemKey="物品7", Num = 3, Bind = 1, Rand={RAND7}},
        {ItemKey="物品8", Num = 1, Bind = 1, Rand={RAND8}},
        {ItemKey="物品9", Num = 3, Bind = 1, Rand={RAND9}},
        {ItemKey="物品10", Num = 5, Bind = 1, Rand={RAND10}},
        {ItemKey="物品11", Num = 1, Bind = 1, Rand={RAND11}},
    }
]]

local baseRand = 5000

local otherRand = {
    30,40,90,40,25,25,90,90,40,25,5
}

for i = 1, 36 do
    if i ~= 1 then
        baseRand = baseRand - 11
        for index, value in ipairs(otherRand) do
            otherRand[index] = value + 1
        end
    end
    local tmpStr = string.gsub(format, "{BASE}", baseRand)
    for index, value in ipairs(otherRand) do
        tmpStr = string.gsub(tmpStr, "{RAND"..tostring(index).."}", value)
    end
    print(tmpStr)
end

运行结果如下

[3] = {
    {ItemKey="nil", Num = 1, Bind = 1, Rand=5000},
    {ItemKey="物品1", Num = 1, Bind = 1, Rand=30},
    {ItemKey="物品2", Num = 1, Bind = 1, Rand=40},
    {ItemKey="物品3", Num = 1, Bind = 1, Rand=90},
    {ItemKey="物品4", Num = 1, Bind = 1, Rand=40},
    {ItemKey="物品5", Num = 1, Bind = 1, Rand=25},
    {ItemKey="物品6", Num = 1, Bind = 1, Rand=25},
    {ItemKey="物品7", Num = 3, Bind = 1, Rand=90},
    {ItemKey="物品8", Num = 1, Bind = 1, Rand=90},
    {ItemKey="物品9", Num = 3, Bind = 1, Rand=40},
    {ItemKey="物品10", Num = 5, Bind = 1, Rand=25},
    {ItemKey="物品11", Num = 1, Bind = 1, Rand=5},
}

[3] = {
    {ItemKey="nil", Num = 1, Bind = 1, Rand=4989},
    {ItemKey="物品1", Num = 1, Bind = 1, Rand=31},
    {ItemKey="物品2", Num = 1, Bind = 1, Rand=41},
    {ItemKey="物品3", Num = 1, Bind = 1, Rand=91},
    {ItemKey="物品4", Num = 1, Bind = 1, Rand=41},
    {ItemKey="物品5", Num = 1, Bind = 1, Rand=26},
    {ItemKey="物品6", Num = 1, Bind = 1, Rand=26},
    {ItemKey="物品7", Num = 3, Bind = 1, Rand=91},
    {ItemKey="物品8", Num = 1, Bind = 1, Rand=91},
    {ItemKey="物品9", Num = 3, Bind = 1, Rand=41},
    {ItemKey="物品10", Num = 5, Bind = 1, Rand=26},
    {ItemKey="物品11", Num = 1, Bind = 1, Rand=6},
}
    <...>
[3] = {
    {ItemKey="nil", Num = 1, Bind = 1, Rand=4615},
    {ItemKey="物品1", Num = 1, Bind = 1, Rand=65},
    {ItemKey="物品2", Num = 1, Bind = 1, Rand=75},
    {ItemKey="物品3", Num = 1, Bind = 1, Rand=125},
    {ItemKey="物品4", Num = 1, Bind = 1, Rand=75},
    {ItemKey="物品5", Num = 1, Bind = 1, Rand=60},
    {ItemKey="物品6", Num = 1, Bind = 1, Rand=60},
    {ItemKey="物品7", Num = 3, Bind = 1, Rand=125},
    {ItemKey="物品8", Num = 1, Bind = 1, Rand=125},
    {ItemKey="物品9", Num = 3, Bind = 1, Rand=75},
    {ItemKey="物品10", Num = 5, Bind = 1, Rand=60},
    {ItemKey="物品11", Num = 1, Bind = 1, Rand=40},
}

可以看到,otherRand表中的数值也正常地发生了改变

一个还在寻找自己的三流开发者