为什么它不能是本地的?

这是我正在运行的安装程序的一个虚拟版本。启动程序函数似乎没有看到 GetLevel。起码第一个打印是看得见的,但第二个不是。所以函数从未开始。是因为代码在它在代码中被启动的地方之后出现,而在 Launcher 执行它的时候它还不存在吗?当我移除本地标记时,它可以工作。所以全局函数可以从脚本的任何地方“看到”,但本地函数只能从代码的后面“看到”? 我试图找出哪些函数可以进行本地化,因为它们都是当前全局的。这有什么好处吗-一个在整个脚本中本地的函数和一个不本地的函数之间有什么区别吗?

local UseLevel = true
local Limit = 0

local function Launcher()
  print("现在尝试启动 GetLevel")
  GetLevel()
end

local function GetLevel()
  print("GetLevel 已启动")
  if UseLevel then
    Limit = 4
  else
    Limit = 5
  end
end

原文链接 https://stackoverflow.com/questions/71102432

点赞
stackoverflow用户734069
stackoverflow用户734069

所以全局函数可以从脚本中的任何位置“看到”,但本地函数只能从代码后面看到?

是的,“全局”意味着全局。

如果您不希望某些内容在脚本外可见,则将其设置为本地内容。除非外部世界需要查看某些内容,否则脚本不应将其暴露给外部世界。只暴露接口,也就是外部代码实际会使用的东西。

2022-02-13 16:06:34
stackoverflow用户7185318
stackoverflow用户7185318

使用局部变量的好处有两个:

第一,局部变量通常更快,因为它们只使用 Lua 虚拟机中的寄存器,而全局变量是全局表中的条目(实际上是哈希表)。调用全局函数需要先索引哈希表。

第二,局部变量有助于提高代码质量,因为它们仅在其局部作用域中可见(比如在文件中或甚至在 if-branch、循环等中)。把所有东西都放在全局作用域中被称为“全局污染”,这是不被赞同的。它也会减慢全局访问速度,因为它会使全局表膨胀。需要注意的是,Lua 允许使用 _ENV(或在旧版中使用 setfenv)来改变环境,因此您有时可以在不污染全局环境的情况下使用这个方法来省略局部关键字和前向声明。通常情况下,您不应该改变环境。

常常使用全局变量来公开接口,正如Nicol Bolas所指出的那样。您也可以在文件末尾使用 return my_api_table,API表可以使用local my_api_table = require(relative_path)进行“导入”。

那是因为代码在启动它的位置之后才出现在代码中,在启动程序执行它的时候它还不存在吗?

是的。您可以使用“前向局部声明”GetLevel来解决这个问题:

local UseLevel = true
local Limit = 0
local GetLevel -- "前向声明"在Launcher之前

local function Launcher()
  print("trying to launch GetLevel now")
  GetLevel()
end

-- 这与 GetLevel = function() ... end 相同,因此不设置全局变量,而是分配给先前声明的局部变量 GetLevel
function GetLevel()
  print("GetLevel was launched")
  if UseLevel then
    Limit = 4
  else
    Limit = 5
  end
end

Launcher 函数简单地放在 GetLevel 之后也可以:

local UseLevel = true
local Limit = 0

local function GetLevel()
  print("GetLevel was launched")
  if UseLevel then
    Limit = 4
  else
    Limit = 5
  end
end

local function Launcher()
  print("trying to launch GetLevel now")
  GetLevel()
end
2022-02-13 16:10:39
stackoverflow用户2858170
stackoverflow用户2858170

其他人已经告诉你一些关于局部变量和全局变量的一般知识。让我们看看你的代码并理解为什么它不起作用。

local UseLevel = true
local Limit = 0

local function Launcher()
  print("trying to launch GetLevel now")
  GetLevel()
end

以上你定义了三个本地变量。一个布尔值,一个数字和一个函数值。 Launcher 调用 GetLevel,假设这是您执行的唯一代码,那么它是一个全局 nil 值。因为在那一行之前,你既没有定义一个名字为GetLevel的本地变量也没有定义一个全局变量。如果你从未为变量分配过值,那么它就是一个 nil 值,如果你从未声明该变量为本地变量,它就是一个全局 nil 值。

然后,您定义了一个名为GetLevel的本地函数。这是一个新的本地变量。它不是你在定义 Launcher 时使用的那个 GetLevel。因为那是全局变量。

local function GetLevel()
  print("GetLevel was launched")
  if UseLevel then
    Limit = 4
  else
    Limit = 5
  end
end

因此,当你稍后调用 Launcher 时,它仍将使用全局 nil 值。而不是它完全不知道的本地值。

使此方法工作的唯一方法是将函数值分配给在 Launcher 定义中使用的相同变量。只要引用相同,范围无关紧要。仅以本地方式使此方法工作的唯一方法是在定义 Launcher 之前声明该本地引用。 无论您是在 Launcher 之前还是之后定义 GetValue,只要在调用 Launcher 时已经定义就可以。

2022-02-14 10:29:17