本节深入剖析Lua变量的作用域、生命周期、存储机制及在Android开发中的最佳实践,包含环境变量、元表控制等高级特性。
Lua中的变量无需类型声明,但作用域控制对Android开发至关重要。
-- 全局变量(应避免)
appName = "MyApp"
-- 局部变量(推荐)
local activityName = "MainActivity"
-- 同时声明多个变量
local x, y, z = 10, 20, 30
-- nil值初始化
local pendingRequest = nil
local dynamicVar = 10 -- 初始为number
print(type(dynamicVar)) -- 输出: number
dynamicVar = "text" -- 改为string
print(type(dynamicVar)) -- 输出: string
dynamicVar = {1, 2, 3} -- 改为table
print(type(dynamicVar)) -- 输出: table
Lua采用词法作用域,理解作用域链对编写高质量Android代码至关重要。
do
local localVar = "内部变量"
print(localVar) -- 输出: 内部变量
end
-- print(localVar) -- 报错: 超出作用域
local outer = 10
function testScope()
local inner = 20
print(outer + inner) -- 输出: 30
do
local deep = 5
print(inner + deep) -- 输出: 25
end
end
local size = 100
function resize()
local size = 200 -- 遮蔽外部size
print("内部:", size) -- 输出: 200
end
print("外部:", size) -- 输出: 100
Lua使用虚拟寄存器架构管理变量,直接影响Android性能优化。
变量类型 | 存储位置 | 访问速度 | 生命周期 |
---|---|---|---|
局部变量 | 寄存器/栈 | 最快 | 作用域内 |
表字段 | 堆内存 | 中等 | 随表存在 |
全局变量 | 全局表(_G) | 最慢 | 永久 |
local value = 10
local t = { value = 20 }
function getValue()
-- 查找顺序: 局部变量 → 上层局部变量 → 表字段 → 全局变量
print(value) -- 输出10(局部变量)
print(t.value) -- 输出20(表字段)
end
Lua 5.2+使用_ENV替代_G,更适合Android模块化开发。
-- 自定义环境
local privateEnv = {
print = function(...)
androidLog(table.concat({...}, "\t"))
end
}
setmetatable(privateEnv, { __index = _G })
local func = load("print('安全执行')", "chunk", "t", privateEnv)
func() -- 通过自定义环境控制访问
-- 跟踪变量访问
local tracker = {}
setmetatable(tracker, {
__index = function(_, k)
print("读取变量:", k)
return rawget(_G, k)
end,
__newindex = function(_, k, v)
print("设置变量:", k, "=", v)
rawset(_G, k, v)
end
})
setfenv(1, tracker) -- 设置当前环境
newVar = 10 -- 输出: 设置变量: newVar = 10
print(newVar) -- 输出: 读取变量: newVar → 10
移动端开发中变量使用的特殊注意事项。
-- 避免循环引用
local button = {}
button.onClick = function()
print(button.text) -- 闭包强引用button
end
-- 正确做法(弱引用)
local weakTable = setmetatable({}, { __mode = "v" })
weakTable.button = button
button.onClick = function(self)
print(self.text) -- 通过参数传递
end
-- 共享变量保护
local sharedData = {}
local lock = java.new("java.util.concurrent.locks.ReentrantLock")
function updateData(key, value)
lock:lock()
sharedData[key] = value
lock:unlock()
end
-- 减少全局访问
local print = print -- 缓存到局部变量
local math_floor = math.floor
for i = 1, 10000 do
-- 使用局部引用
print(math_floor(i / 2))
end