上一回在研究 rom/programs/monitor.lua 的过程中
看到一些大写的变数 _G, _ENV
心想,该是来面对它们的时候了!
先说在 Lua 5.1 或之前的版本
当我们宣告一个全域变数的时候,会自动被存入 _G
这个全域的 table
a = 1
b = "2"
function c()
print(3)
end
print(_G.a) -- 1 _G["a"] 的语法糖
print(_G.b) -- 2 _G["b"] 的语法糖
print(_G.c) -- function: 0x13dc770
_G["c"]() -- 3
如上述程序码,存取 _G 里面的元素时,已经预设是全域,不必再指定 _G
并且可以透过在 _G 存入新的值,来宣告全域变数
a = 1
print(a) -- 等同 print(_G.a) 或 print(_G["a"])
_G["d"] = true
print(d) -- true
而事实上,之前我一直在使用的 Lua 内建函式库
也都会存入 _G 这个大表中,也因此我才可以直接呼叫 table.insert(), io.read(), os.date() 等等
print(io) -- table: 0x195cff0
print(string) -- table: 0x1956ac0
print(table) -- table: 0x19588c0
print(table.insert) -- function: 0x42b750
print(os) -- table: 0x19598d0
print(os.date) -- function: 0x4272d0
print(print) -- function: 0x4215c0 最常用的 print,也是全域函数
如果想要让变数环境单纯一点,而不是每次都去更动 _G 大表呢?
Lua 5.1 提供了 setfenv 方法,可以改变函数的环境
x = 1
myEnv = {}
setfenv(1, myEnv)
print(x) -- 这边会出错,因为全新的环境 myEnv 还没有任何变数或方法,就连 print() 都没有 !
可以用继承来解决,所有原本 _G 的变数与方法都会继承
x = 1
myEnv = {}
setmetatable(myEnv, { __index = _G })
setfenv(1, myEnv)
print(x)
Lua 5.2 开始,加入了新的 _ENV
环境
a = 1 相当於 _ENV['a'] = 1
但是 _G 还是可以使用,只是 _ENV["_G"] 指向了 _ENV
也就是 _ENV["_G"] = _ENV,这是为了相容 Lua 5.1 或更旧的程序码
a = 1
b = 2
print(_ENV.a)
print(_G.b) -- 相当於 print(_ENV["_G"].b)
此外 setfenv 函数已经废弃,要在 Lua 5.2 自订变数环境
则是需要自行宣告新的 _ENV 如下
a = 1
function myfunc()
local _ENV = { print = print, myvar1 = 2 }
myvar2 = false
print(myvar1) -- 2
print(_ENV.myvar2) -- false
print(_ENV.a) -- nil 已经是新的环境变数,所以看不到外面的变数 a
end
myfunc()
print(_ENV.a) -- 1
print(_ENV.myvar1) -- nil 看不到在函数内自定义的环境变数
对环境变数的实验与学习先到这里
觉得已经愈来愈清楚 Lua 的整个环境与架构设计
下次来研究 Lua 的 coroutine 函式库
今日文章目录 需求说明 事前准备 过程纪录 参考纪录 需求说明 在每个ToDoList项目中,纪录...
在上一个章节,我们已经建立了一个Datatstore及Container,也上传资料到Contain...
昨天跟朋友聊到中华电信,想说写篇文章来分析一下众多投资人喜爱的标的。 我後来跟大家询问一下,发现好多...
Before learning the front-end web development, let...
什麽是云端服务 ? 云端服务指的就是将软硬体等资源,放到网际网路上作为服务,使用者只需透过网路,就可...