关于模块/需求的Lua范围问题

时间:2011-02-15 11:07:25

标签: scope lua

我正在使用准模块方法“从表中 - 在内部使用本地”,如this page所述。

local M = {}

-- private
local x = 1
local function baz() print 'test' end

local function foo() print("foo", x) end
M.foo = foo

local function bar()
  foo()
  baz()
  print "bar"
end
M.bar = bar

return M

但是,在定义函数后,我没有向模块表中添加函数等。相反,我会在文件的底部进行操作。

local x = 1
local function baz() print 'test' end

local function foo() print("foo", x) end

local function bar()
  foo()
  baz()
  print "bar"
end

local M = {
  bar = bar,
  foo = foo,
}
return M

可以清楚地看到M是一个局部变量。我想知道是否改变了

local x = 1
local function baz() print 'test' end

local function foo() print("foo", x) end

local function bar()
  foo()
  baz()
  print "bar"
end

return {
  bar = bar,
  foo = foo,
}

是等价的。我想如果我在另一个像

中使用这个模块那么返回的表是全局的但是afaik
local foo = require 'foomodule'

它没有区别(performancewise)因为我将局部变量foo绑定到返回的表。

1 个答案:

答案 0 :(得分:5)

简短版本:所有这些代码片段都是等效的。

显然,创建全局模块表取决于用户编写模块。 require"foomodule"正确加载模块,但它不会在globals表foomodule中创建_G表。它确实在package.loaded中创建了一个模块表。

所以基本上这是你的选择:

  1. 在您的模块中生成全局模块表,只需require "foomodule"即可创建全局foomodule表
  2. 将决定权交给用户:执行第三个代码段,然后返回一个未命名的表。
  3. 在我看来,选项2是首选,因为它不会意外毁坏与您的模块同名的用户表,或者至少他知道如果他看到foo = require'...'他正在擦除他的表。然而,似乎大多数模块使用第一种方法,只是希望不会发生这个问题。

    至于当地人,这很简单,本地人是本地人;)。因此,如果您声明一个本地,它只在声明的范围内可用(参见参考手册中的section 2.6: Visibility)。