当你加载一个 Lua 文件时,你实际上是在执行它的代码。和其他语言的 DLL 或其他文件类型不同:
int luaL_dofile (lua_State *L, const char *filename);
加载并运行指定的文件。它定义为以下宏:
如果你的文件内容如下:
function sayHello()
print('Hello, world!')
end
那么加载该文件将在全局对象上创建一个名为 'sayHello' 的函数。如果再次加载该文件,它将用新函数替换现有函数,而且不会出现内存泄漏。调用 'sayHello' 的任何人都将在全局对象上调用新函数,除非他们已经保存了原始函数的引用。代码通常这样做,因为调用局部变量比调用全局函数稍微快一些。例如,如果另一个文件在顶部有 local sayhi = sayHello,那么对 'sayhi' 的任何调用都将调用原始函数。
如果你正在创建类并期望数据保留,任何在重新加载之前创建的对象(Lua 表)仍将引用旧类的 metatable。你的新类的代码不会自动应用于在重新加载之前创建的类。
以 Lua 文档中的示例为例:
Account = {}
function Account:deposit (v)
self.balance = self.balance + v
end
function Account:new (o)
o = o or {} -- create object if user does not provide one
setmetatable(o, self)
self.__index = self
return o
end
a = Account:new{balance = 0}
a:deposit(100.00)
现在,a 是一个具有 'balance' 属性为 100.00 和元表指向 Account 表的表。如果你修改 deposit 函数以便打印余额并重新加载文件,它将替换全局 'Account' 表和函数,但表 'a' 将仍然具有原始的 Account 表作为它的元表。因此,调用 'a.deposit' 将仍然不会打印该值。