Lua程序设计(五十二)

Lua语言没有真正的全局变量,而是通过_ENV模拟全局变量的机制。编译器将自由名称转换为_ENV.x的形式,其中_ENV是一个预定义的上值,初始值可为任意表,通常用于模拟全局环境。在函数load时,会使用全局环境初始化第一个上值。_ENV本身只是一个变量,并无特殊含义,其引用遵循可见性规则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

非全局环境

Lua语言中,全局变量不一定非得是真正全局的。Lua语言中甚至都根本没有全局变量。但是Lua语言尽力让程序员有全局变量存在的幻觉。那么Lua语言是如何模拟全局变量的存在的呢?

首先,让我们从自由名称的概念开始讨论。一个自由名称是指没有关联到显式声明上的名称,即它不出现在对应局部变量的范围内。

local z = 10
x = y + z

xy 是自由名称,而 z不是。

接下啦就到了关键的部分:Lua语言编译器将代码段中的所有自由名称 x 转换为 _ ENV.x。因此,上述代码段完全等价为:

local z = 10
_ENV.x = _ENV.y + z

那么_ ENV 变量是什么呢?

正如我们之前提到的, Lua 语言没有全局变量。 因此, _ ENV 不可能是全局变量。在这里,编译器实际上将原来的代码段编译为如下形式:

local _ENV = some value(某些值)
return function (...)
	local z = 10
	_ENV.x = _ENV.y + z
end

也就是说,Lua 语言是在一个名为 _ ENV 的预定义上值(一个外部的局部变量, upvalue)存在的情况下编译所有的代码段的。 因此,所有的变量要么是绑定到了一个名称的局部变量, 要么是 _ ENV 中的一个字段, 而_ ENV 实际上本事是一个局部变量(一个上值)。

_ ENV 的初始值可以是任意的表( 实际上也不用一定是表)。 任何一个这样的表都被称为一个环境。为了维持全局变量存在的幻觉, Lua 语言在内部维护了一个表来用做全局变量( global environment )。 通常,当加载一个代码段时,函数 load 会使用预定义的上值来初始化全局环境。

local _ENV = the global environment
return function (...)
	local z = 10
	_ENV.x = _ENV.y + z
end

总结一下 Lua语言中处理全局变量的方式:

  • 编译器在编译所有代码前, 在外层创建局部变量 _ ENV;
  • 编译器将所有自由名称 var 变换为 _ ENV.var;
  • 函数 load (或函数 loadfile )使用全局环境初始化代码段的第一个上值,即 Lua 语言内部维护的一个普通的表。

其实, _ ENV 只是一个单纯的变量。抛开编译器,名称 _ ENV 对于 Lua 语言来说根本没有任何的特殊含义。 类似地,从 x 到 _ ENV.x 的转换纯粹是语法上的转换,没有隐藏的含义。按照标准的可见性规则, _ ENV 引用的是其所在位置所有可见的 _ ENV 变量。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值