Lua 局部函数不选择局部变量成员,除非在声明时赋值

Lua local function does not pick local variable members except if assigned at declaration

以下代码有效:

local randomPick = {
    currentPick = 'N/A',
    pickNode = function(self)
        randomPick = node.random(1, table.getn(availableNodes));
        self.currentPick = availableNodes[randomPick];
        return self.currentPick
    end
};

local sentF = function(port, ip, data)
    print('Sent info to ' .. randomPick.currentPick);
end

但是如果我在声明 randomPick 之后赋值,我会得到一个错误:

local randomPick = {};
randomPick.currentPick = 'N/A';
randomPick.pickNode = function(self)
        randomPick = node.random(1, table.getn(availableNodes));
        self.currentPick = availableNodes[randomPick];
        return self.currentPick
    end

local sentF = function(port, ip, data)
    print('Sent info to ' .. randomPick.currentPick);
end

这不起作用并抛出此错误。当我为这 2 个成员赋值时,为什么函数选择一个空的 randomPick

PANIC: unprotected error in call to Lua API (attempt to index upvalue '?' (a number value))

您创建本地 table randomPick.

调用 randomPick.pickNode 后,您会用随机数值覆盖 table randomPick

如果您随后调用 setnF,您将索引局部上值 randomPick,这是一个数字。

local randomPick = {};
randomPick.currentPick = 'N/A';
randomPick.pickNode = function(self)
   local randomPick = node.random(1, table.getn(availableNodes));
   self.currentPick = availableNodes[randomPick];
   return self.currentPick
end

local function sentF(port, ip, data)
    print('Sent info to ' .. randomPick.currentPick);
end

这应该可以解决;问题是你在没有声明新本地的情况下使用了两次 randomPick,所以你只是覆盖了你的变量。

当您调用 pickNode 时,它会将 randomPick 设置为一个新值,然后当您尝试对其进行索引时,您会收到错误消息,因为它现在是一个数字。

你应该问的问题是为什么它甚至在第一个例子中起作用,而且局部变量在赋值之后才在范围内,所以 function 不认为它是一个本地并因此尝试将其作为全局访问。

发生的事情是这样的:

local function f(self)
   -- randomPick isn't a local variable yet, so the function is compiled
   -- to use _ENV.randomPick at this point
   randomPick = node.random(1, table.getn(availableNodes));
   self.currentPick = availableNodes[randomPick];
   return self.currentPick
end

local randomPick = {};
-- Local randomPick is introduced here, shadowing the global _ENV.randomPick
randomPick.currentPick = 'N/A'
randomPick.pickNode = f

local function sentF(port, ip, data)
    print('Sent info to ' .. randomPick.currentPick);
end