首页
统计
壁纸
追番记录
优秀博主
关于
推荐
导航
工具
音乐解锁
Search
1
NAS的简单介绍
729 阅读
2
网站环境一键部署工具推荐
505 阅读
3
tp5-模型数据处理
404 阅读
4
win10镜像
358 阅读
5
第20200225期-电脑壁纸-P10
350 阅读
PHP
闲谈杂料
硬件系统
美图
ThinkPHP
笔记
数据库
Lua
登录
Search
标签搜索
ThinkPHP
MySQL
Laravel
PHP
API
GIT
Windows10
markdown
Web
跨域
ajax
小程序
壁纸
Linux
jsonp
try
异常
Dcat
UEFI
win10
phpfunny
累计撰写
104
篇文章
累计收到
24
条评论
首页
栏目
PHP
闲谈杂料
硬件系统
美图
ThinkPHP
笔记
数据库
Lua
页面
统计
壁纸
追番记录
优秀博主
关于
推荐
导航
工具
音乐解锁
搜索到
1
篇与
的结果
2025-04-02
【Lua基础】作用域
作用域区别在 Lua 中,function 和 local function 的主要区别在于它们的作用域(scope):function 声明:创建一个全局函数可以在声明之前被调用(函数提升)在整个程序中都可以访问会被添加到全局环境表中(通常是 _G 表)local function 声明:创建一个局部函数只能在声明之后被调用(没有函数提升)只在声明它的作用域内可见(比如在文件内或特定代码块内)不会污染全局命名空间访问速度更快(因为不需要在全局表中查找)内存效率更高(当离开作用域后可以被垃圾回收)建议:除非特别需要在其他模块中使用该函数,否则优先使用 local function使用 local function 可以避免命名冲突使用 local function 可以让代码更容易维护和理解,因为函数的作用域更明确作用域规则Lua 的作用域规则相对简洁,但灵活性强:默认全局变量 :未用 local 声明的变量默认是全局的。局部变量 :用 local 声明的变量仅在当前块(如函数、循环、代码块)内有效。作用域链 :内层作用域可以访问外层作用域的变量(遵循词法作用域规则)。local outer = 10 -- 外层局部变量 function test() local inner = 20 -- 函数内的局部变量 print(outer) -- 可以访问外层变量(输出 10) end test() print(inner) -- 错误:inner 在此作用域不可见 高级技巧1. 显式块级作用域(do...end)通过 do...end 创建临时作用域, 限制局部变量的生命周期 :do local temp = "临时变量" print(temp) -- 输出 "临时变量" end -- print(temp) 此处访问会报错(temp 已超出作用域) 用途 :避免变量污染全局命名空间。控制资源释放(如文件句柄)。2. 闭包与 UpvalueLua 的闭包(Closure)可以 捕获外层函数的局部变量 (称为 upvalue ),并保持其状态function counter() local count = 0 return function() -- 返回闭包函数 count = count + 1 return count end end local c1 = counter() print(c1()) -- 输出 1 print(c1()) -- 输出 2(闭包保留了 count 的状态) 特性 :Upvalue 的生命周期与闭包绑定,即使外层函数已返回。多个闭包共享同一个 Upvalue 时,修改会互相影响。3. 环境控制(_ENV 与 setfenv)Lua 通过 环境(Environment) 控制全局变量的访问,可用于沙盒隔离或模块化开发。(1) 修改函数环境-- 创建一个纯净的环境(无全局变量) local clean_env = { print = print } -- 只允许访问 print local code = [[ a = 10 -- 不会污染全局环境 print(a) -- 输出 nil(因为 clean_env 中无 a) ]] local func = load(code, "sandbox", "t", clean_env) func() (2) 使用 _ENV 元表通过元表实现环境继承:local shared_env = { x = 100 } setmetatable(shared_env, { __index = _G }) -- 继承全局环境 local code = [[ print(x) -- 输出 100(来自 shared_env) print(math.pi) -- 输出 3.1415(继承自 _G) ]] load(code, "env_test", "t", shared_env)() 4. 模块模式利用闭包和表返回实现模块封装:local mymodule = (function() local private = "私有数据" local function get() return private end local function set(value) private = value end return { get = get, set = set } -- 暴露接口 end)() print(mymodule.get()) -- 输出 "私有数据" mymodule.set("新值") print(mymodule.get()) -- 输出 "新值" 优点 :隐藏内部实现细节。避免全局命名冲突5. 动态作用域模拟Lua 默认是词法作用域,但可通过 debug 库模拟动态作用域(慎用):function dynamic_scope() local var = "动态值" local function inner() print(debug.getlocal(2, 1)) -- 获取调用者的局部变量 end inner() end dynamic_scope() -- 输出 nil(需要特定上下文) 建议:优先使用局部变量 :减少全局污染,提升性能(局部变量访问更快)。合理使用闭包 :注意内存泄漏风险(长期持有的闭包可能阻止 Upvalue 释放)。模块化设计 :通过环境控制或闭包封装功能。避免滥用动态作用域 :保持代码可预测性。
2025年04月02日
9 阅读
0 评论
0 点赞