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

下面的代码可行:

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('已将信息发送至 ' .. 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('已将信息发送至 ' .. randomPick.currentPick);
end

这样是不行的,会出现以下错误。为什么函数会选择空的 randomPick,而这个变量的两个成员已经被赋值了?

PANIC: 在调用Lua API时出现未受保护的错误(尝试索引上值 '?'(一个数字值))

点赞
用户2858170
用户2858170

你创建了一个名为 randomPick 的本地表。

一旦调用 randomPick.pickNode,将使用随机数字值覆盖该表 randomPick

如果你随后调用 setnF,则将索引本地的上值 randomPick,其为数字。

2019-12-01 18:31:12
用户4984564
用户4984564
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设置为一个新的值,当你尝试索引它时,就会出现错误,因为它现在是一个数字。

你应该问的问题是为什么在第一个示例中这个代码甚至可以工作,原因就是这个局部变量在赋值之后才能在作用域中使用,所以函数看不到它是一个局部变量,因此尝试将其作为全局变量来访问。

发生的事情大致如下:

local function f(self)
   -- 在randomPick还不是局部变量之前,函数就已经使用_ENV.randomPick把它编译了
   randomPick = node.random(1, table.getn(availableNodes));
   self.currentPick = availableNodes[randomPick];
   return self.currentPick
end

local randomPick = {};
-- 在这里引入局部变量randomPick,会遮蔽全局变量_ENV.randomPick
randomPick.currentPick = 'N/A'
randomPick.pickNode = f

local function sentF(port, ip, data)
    print('Sent info to ' .. randomPick.currentPick);
end
2019-12-01 20:06:10