- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
摘录自Lua 5.3 manual:
_G
保存全局环境的全局变量(不是函数)(请参见§2.2)。 Lua本身不使用此变量。更改其值不会影响任何环境,反之亦然。
§2.2的相关部分
[…]每个块都在名为_ENV
的外部局部变量的范围内编译,因此_ENV
本身绝不是块中的自由名称。
[…]
任何用作_ENV
值的表都称为环境。
Lua保留了一个称为全球环境的杰出环境。此值保存在C注册表中的特殊索引处。在Lua中,全局变量_G
用相同的值初始化。 (_G
从未在内部使用。)
当Lua加载一个块时,其_ENV
上值的默认值是全局环境。因此,默认情况下,Lua代码中的自由名称引用全局环境中的条目
我知道对于每个加载的块,由于_ENV
将是第一个升值,因此它指向全局环境表,由_G
指向load
。
> =_G, _ENV
table: 006d1bd8 table: 006d1bd8
_ENV
和
_G
只是常规名称,没有隐藏的含义,并且Lua本身不在内部使用它。我在下面尝试了这个块:
local a = { }
local b = a -- since tables are objects, both refer to the same table object
print(a, b) -- same address printed twice
a = { } -- point one of them to a newly constructed table
print(a, b) -- new, old table addresses printed
_G
和
_ENV
做同样的事情:
local g = _G -- make an additional reference
print(g, _G, _ENV) -- prints same address thrice
local p = print -- backup print for later use
_ENV = { } -- point _ENV to a new table/environment
p(g, _G, _ENV) -- old, nil, new
table: 00ce1be0 table: 00ce1be0 table: 00ce1be0
table: 00ce1be0 nil table: 00ce96e0
_G
是普通的全局变量,为什么在这里变成
nil
?如果引用计数已完成,则
_G
在发布
_ENV
时仍保留引用。像上面的
b
一样,它也应该保留旧表,不是吗?
_G
不变/保留!
_ENV = { _G = _G }
_G.print(_G, _ENV, _ENV._G) -- old, new, old
_ENV = { g = _G }
_ENV.g.print(_ENV, _ENV.g, _G) -- new, old, nil
print(_G, _ENV) -- print same address twice
local newgt = {} -- create new environment
setmetatable(newgt, {__index = _G}) -- set metatable with _G as __index metamethod
_ENV = newgt -- point _ENV to newgt
print(_G, newgt, _ENV) -- old, new, new
_G
的行为有很多变化,因此手册给出的最初保证似乎有些不稳定。我在这里想念什么?
最佳答案
全局变量_G
有多特殊?
它以三种方式很特殊:
它使用名称reserved for internal use by Lua。
它是由Lua的标准模块之一(特别是
"base"模块)。如果您创建一个新的lua_State
而没有
打开“基本”模块,您将没有_G
变量。的
独立解释器已加载了所有标准库,
虽然。
一些第三方Lua模块使用全局变量_G
,并且
更改/删除它可能会破坏这些模块。_G
有什么意义?
Lua中的全局变量是使用普通表实现的。任何
访问不是local
变量或上限值的变量
重定向到该表。局部变量始终具有优先权,因此
如果您有一个具有相同名称的全局变量和局部变量,
您将永远得到本地的。 _G
在这里起作用:如果
如果需要全局变量,可以说_G.name
而不是name
。
假设名称_G
不是局部变量(保留给Lua,
还记得吗?!),这将始终为您提供全局变量的值
通过使用表索引语法,从而消除与
局部变量名称。在较新的Lua版本(5.2+)中,您也可以使用_ENV.name
作为替代,但_G
早于这些版本,并且
保持兼容性。
在其他情况下,您想掌握全局变量
桌子,例如用于设置一个元表。 Lua允许您自定义
表的行为(和其他值),方法是使用setmetatable
函数,但是您必须将表作为
参数。 _G
可以帮助您做到这一点。
在某些情况下,如果您向全局表添加了一个元表
您可能想规避元方法(__index
和/或__newindex
)刚刚安装。您可以使用rawget
和rawset
,但是您需要将globals表作为参数传递
也一样
请注意,上面列出的所有用例仅适用于Lua代码,不适用于
C代码。在C代码中,您没有命名局部变量,仅堆栈
索引。因此没有歧义。如果您想参考
全局表传递给某些功能,可以使用lua_pushglobaltable
(用uses the registry代替_G
)。
结果,用C实现的模块不需要/不需要_G
全局变量。这适用于Lua的标准库(
同样在C)中实现。实际上,参考手册
guarantees,即未使用_G
(变量,而不是表)
由Lua或其标准库提供。_G
与_ENV
有何关系?
从5.0版开始,Lua允许您更改用于查找的表
基于(Lua)函数的全局变量。在Lua 5.0和5.1中
您为此使用了setfenv
函数(globals表是
也称为“功能环境”,因此命名为setfenv
。 Lua 5.2
引入了使用另一个特殊变量名称_ENV
的新方法。
虽然_ENV
不是全局变量,但Lua确保每个
块以_ENV
升值开头。新方法通过让
Lua将对非本地(和非上值)变量的所有访问权限转换为
将a
命名为_ENV.a
。无论什么时候_ENV
在代码中
习惯于解析全局变量。这样更安全,因为
您无法更改未编写自己的代码的环境
(无需使用调试库),并且也更加灵活,因为您
可以通过创建更改单个代码块的环境local
_ENV
范围有限的变量。
但是,无论如何,您都需要使用默认环境
在程序员有机会设置自定义变量之前(或者如果程序员
不想更改它)。在启动时,Lua创建此默认值
您和商店的环境(也称为"global environment")
在registry中。此默认环境用作
除非您将自定义环境传递到,否则所有块的_ENV
增值load
或loadfile
。也lua_pushglobaltable
直接从注册表中检索此全局环境,因此
所有C模块都会自动使用它来访问全局变量。
如果已加载标准的“基本” C模块,则此
默认的“全局环境”具有一个名为_G
的表字段,该字段引用
回到全球环境。
把它们加起来:
全局变量_G
实际上是_ENV._G
。_ENV
不是全局变量,而是上限值或局部变量。
默认“全局环境”的_G
字段指向
全球环境。
默认情况下,_G
和_ENV
引用同一表(表示全局
环境)。
C代码既不使用,也不使用注册表中的一个字段(
再次根据定义指向全球环境)。
您可以在全局环境中替换_G
(在全局环境中)
C模块或Lua本身(但您可能会破坏第三方Lua
模块(如果不小心)。
您可以随时替换_ENV
,因为它只会影响
您自己的代码(最多当前块/文件)。
如果替换_ENV
,则可以自行决定是否_G
(_ENV._G
)将在受影响的代码中显示
指着。
关于lua - 全局变量_G有多特殊?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35910099/
我以一种特殊的方式收到以下错误。 The point at which the driver is attempting to click on the element was not scrolle
我有一些包含如下方法的编译库: public boolean foo(String userID) { Class ntSystemClass = Thread.currentThread()
假设我有下表 name | genre --------------------- book 1 | scifi book 2 | horror book 3
我正在用代码进行语言翻译。 self.title.text = [NSString stringWithFormat:NSLocalizedString(@"Q%ld", nil), (long)qu
我想这样做,但到目前为止,我所拥有的只是: print("Will you go out with me?") 我希望代码能够正常工作,以便人们可以回答“是/否”,如果回答是"is",则将返回一条消息
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: How can I decode html characters in c#? 我有来自 HTML 的字符,
我想在 JavaScript 中对以下形式的字符串执行 ucwords(),它应该返回 Test1_Test2_Test3。 我已经在 SO 上找到了一个 ucwords 函数,但它只需要空格作为新词
“任何长度的正数表示为数字字符数组,因此介于‘0’和‘9’之间。我们知道最重要的密码位于数组索引 0 的位置。 例子: - 号码是 10282 - 数组将是数字 = [1,0,2,8,2] 考虑到这一
我目前正在开发一个显示特殊 unicode 字符(例如 ꁴ)的应用 现在我遇到了在旧设备上无法显示这些符号的问题。我如何知道它是否适用于当前设备? 我是否必须为每个 SDK 版本创建一个虚拟 Andr
在 HTML、XML 和部分 DTD 中,有两种特殊的标记结构: 以感叹号开头的标签结束,例如 和 以问号开头的标签 ,例如 和 我的问题是,这些构造类型中的每一种是否都有不同的名称,或者我是否必
我目前正在用 python 构建一个 shell。shell 可以执行 python 文件,但我还需要添加使用 PIPE 的选项(例如“|”表示第一个命令的输出将是第二个命令的输入)。 为了做到这一点
我的 MVC 项目中的路由无法正常工作... 我希望我所有的 View 都在 Views > Shared 文件夹中,如下所示: Error.cshtml (default) Index.cshtml
我有一个函数: public static ImageIcon GetIconImageFromResource(String path){ URL url = ARMMain.class.g
好的,所以我想在我的 html 页面中包含下面的字符。看起来很简单,只是我找不到它们的 HTML 编码。 注意:我想在没有大小元素的情况下执行此操作,纯文本就可以了 ^_^。 干杯。 最佳答案 你可以
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 3 年前。
我是 C# 的新手,正在尝试使用 ASP.Net GridView(框架 3.5),当 gridView 文本包含以下内容时,我发现了一个大问题: ñ/Ñ/á/Á/é/É/í/Í/ó/Ó/ú/Ú or
在 Java 中,我尝试编写一个正则表达式来匹配特殊类型的 HTTP URL: http:///# 所以字符串有 4 段: 字符串文字:“http://”;那么 任意 1 个以上字符的字符串;那么 字
当我写查询时,我在表中有“to”列 SELECT to FROM mytable mysql_error 返回错误,如果将单词to插入``引号,即 SELECT `to` FROM mytable 查
我遇到了一个问题。事实上,我使用越南语文本,我想找到每个包含大写字母(大写字母)的单词。当我使用“re”模块时,我的函数 (temp) 没有捕捉到像“Đà”这样的词。另一种方法 (temp2) 是一次
在我的文本中,我想用一个空格替换以下特殊字符: symbols = ["`", "~", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_",
我是一名优秀的程序员,十分优秀!