函数内的变量在每次调用时不会被重置(LUA)

我正在尝试设置一个函数,以将分钟添加到当前时间对象并返回一个新的时间对象。我为此创建了一个函数,但由于某种原因,函数中的变量没有被重新设置/本地化,每次调用函数时都会使用函数内部的过去值。为什么?

```lua local function AddTime (MinAfter, BaseTime)

if (MinAfter == nil) then  MinAfter = 0 end
if (BaseTime == nil) or (BaseTime.min == nil) or (BaseTime.hour == nil)  then  BaseTime = os.date("*t") end

BaseTime.hour = BaseTime.hour + math.floor((BaseTime.min + MinAfter)/60)
BaseTime.min =  BaseTime.min + MinAfter - (60 * (math.floor((BaseTime.min + MinAfter)/60)))

if BaseTime.hour > 24 then  BaseTime.hour = 24 end

return  BaseTime

end

local sunriseHour = os.date("*t" ,os.time {year = 2014, month = 4, day = 19, yday = 259, wday = 4, hour = 6, min = 0, sec = 0, isdst = false});

--这是原始时间对象,在这种情况下为sunraiseHour print ("sunriseHour time:" .. (string.format("%02d",sunriseHour.hour) .. ":" .. string.format("%02d", sunriseHour.min)));

--第一次调用 local newtime1= AddTime(10, sunriseHour); print ("call 1 time:" .. string.format("%02d", newtime1.hour) .. ":" .. string.format("%02d", newtime1.min));

--在第一次调用中,我得到了07:10,这是正确的

--第二次调用 local newtime2= AddTime(10, sunriseHour); print ("call 1 time:" .. string.format("%02d", newtime2.hour) .. ":" .. string.format("%02d", newtime2.min));

--在第二次调用中,我得到了07:20而不是07:10,因为这是第二次调用该函数 - 函数内部的BaseTime变量没有被本地化。

点赞
用户501459
用户501459

当你把 sunriseHour 传入 AddTime 时,它是通过引用传递而不是值传递的,这意味着在 AddTime 中对 BaseTime 进行的任何更改都是对 sunriseHour 进行的更改——两个变量(sunriseHourBaseTime)都指向同一个对象。

因此,当您在 AddTime 中编写以下内容时:

BaseTime.hour = BaseTime.hour + math.floor((BaseTime.min + MinAfter)/60)
BaseTime.min =  BaseTime.min + MinAfter - (60 * (math.floor((BaseTime.min + MinAfter)/60)))

您正在修改 sunriseHour

看来您并没有完全理解这一点,因为您还在 AddTime 中为 BaseTime 赋予了一个新值,这表明您认为您有一个新对象。如果您想要创建一个改变后的 sunriseHour 的副本,那么您需要在 AddTime 中完成这个任务,或者为您的时间对象创建一些类型的复制构造函数。

2014-04-19 20:03:11
用户3532518
用户3532518

感谢 Mud, 我明白了我需要复制我的时间对象,否则由于我使用它的引用,它会修改原始对象。 我找到了一个复制函数,并在函数内部使用它将对象复制到本地。

谢谢

function table.copy(orig)
    local orig_type = type(orig)
    local copy
    if orig_type == 'table' then
        copy = {}
        for orig_key, orig_value in pairs(orig) do
            copy[orig_key] = orig_value
        end
    else -- number, string, boolean, etc
        copy = orig
    end
    return copy
end

 function AddTime (MinAdd, TimeObj)

local BaseTime = {};
local MinAfter = 0;

if (TimeObj == nil) or (TimeObj.min == nil) or (TimeObj.hour == nil) then  BaseTime =  table.copy(os.date("*t")) else  BaseTime = table.copy(TimeObj)  end;
if (MinAdd == nil) then  MinAfter = 0 else MinAfter = MinAdd end;

    BaseTime.hour = BaseTime.hour + math.floor((BaseTime.min + MinAfter)/60)
    BaseTime.min =  BaseTime.min + MinAfter - (60 * (math.floor((BaseTime.min + MinAfter)/60)))

  if BaseTime.hour > 24 then  BaseTime.hour = 24 end

  return  BaseTime

end

        -- 这是原始时间对象,在这种情况下为sunraiseHour
         local sunriseHour = os.date("*t" ,os.time {year = 2014, month = 4, day = 19, yday = 259, wday = 4, hour = 6, min = 0, sec = 0, isdst = false});

              print ("sunriseHour time:" .. (string.format("%02d",sunriseHour.hour) .. ":" .. string.format("%02d", sunriseHour.min)));

        -- 第一次调用

        local newtime1= AddTime(10,sunriseHour);

              print ("call 1 time:" .. string.format("%02d", newtime1.hour) .. ":" .. string.format("%02d", newtime1.min));

             -- 在第一次调用时,我得到了 07:10,这是正确的

        -- 第二次调用

        local newtime2= AddTime(10,sunriseHour);

              print ("call 2 time:" .. string.format("%02d", newtime2.hour) .. ":" .. string.format("%02d", newtime2.min));

              -- 在第二次调用中,我得到了 07:20 而不是 07:10,因为这是对函数的第二次调用 - 函数内的 BaseTime 变量变成了全局变量

                        print ("Added time:" .. string.format("%02d", AddTime(20, sunriseHour).hour) .. ":" .. string.format("%02d", AddTime(20, sunriseHour).min));
2014-04-19 20:35:51