| 一、什么是函数 函数是对语句和表达式进行抽象的主要方法,用来处理复杂工作或计算数值。 生活例子:去饭店点菜 错误做法:对服务员说"你给我打个鸡蛋,打碎,搅拌,放油,炒到金黄,盛出来,再拿两个西红柿,切开,放油,放盐,盛出来,把这两盘菜给我" 正确做法:直接说"我要一份西红柿炒鸡蛋" 核心概念:调用函数时,不需要关心中间过程,直接获取结果即可。函数就是一个"菜单",点菜(调用)后厨师(函数)做好直接端上来(返回结果)。 二、函数的基本结构函数由三部分组成:关键字function、函数名、括号、函数体、结束标记end 基础调用方式:先定义函数,再通过"函数名+括号"进行调用。只定义不调用,函数不会执行。 内存位置:函数存放在堆内存中。栈内存存放临时变量和参数,堆内存存放数据表和函数。理解堆栈对后期学习作用域、内存优化和逆向工程很重要。 三、全局函数与局部函数全局函数:默认情况下定义的函数是全局的,会一直存在于内存中等待被调用。 局部函数:使用local关键字定义的函数,当超出作用域后会被自动清理(内存回收)。 局部函数的本质:函数本身仍在堆内存中,但函数名(引用)放在栈上。局部的是引用,不是函数本身。 四、返回值 return返回值决定函数是否需要产生结果。 无返回值:只需要函数执行某个动作,不关心结果。例如"帮我把卫生打扫了",不需要汇报打扫过程。 有返回值:需要函数执行后给出结果。例如"制作番茄炒蛋",完成后要把菜端上来。 返回值会传递给调用者。可以用变量接收返回值,也可以直接打印。 五、参数参数可以理解为函数内部的局部变量,在函数调用时传入。 参数的作用:让函数可以处理不同的数据,而不是固定值。调用时传入实际数值,函数内部用参数名接收。 参数特性: - 参数数量没有严格限制
- 传入的参数和定义的参数按位置一一对应
- 传入的参数个数可以和定义的不一致,多余的被忽略,缺少的变为nil
- 参数名可以与外部变量名不同,内部会自动赋值
实际应用示例:验证账号密码的函数,传入用户名和密码两个参数,在函数内部进行判断,正确返回管理员上线,密码为空则提前返回并提示。 六、多返回值Lua支持函数返回多个值,这是Lua的特色之一。 实现方式:在return后面用逗号分隔多个返回值。 接收方式:调用时用多个变量按顺序接收,变量之间用逗号分隔。 注意事项: - 用多个变量接收时,按顺序一一对应
- 只用单个变量接收时,只获得第一个返回值,其余被忽略
- 用四个变量接收四个返回值,可以全部获取
七、匿名函数匿名函数是没有名字的函数,直接定义在赋值语句中。 定义方式:变量名 = function(参数) 函数体 end 与普通函数的区别: - 普通函数有名字,全局存在,一直等待被调用
- 匿名函数通过变量引用,如果是局部变量,超出作用域后函数会被清理
- 执行速度和使用方式完全相同
使用场景:临时性操作,用完即销毁,不需要长期保留在内存中。 八、函数类型检测使用type函数可以检测数据类型。无论普通函数还是匿名函数,检测结果都是"function"。Lua不关心函数是否有名字,只识别它是函数类型。 九、闭包(初步了解)闭包是一种高级函数形式,指函数内部返回另一个函数,并且内部函数可以访问外部函数的局部变量。 核心特性:内部函数会"抓取"外部函数的局部变量,即使外部函数执行完毕,这个变量也不会被销毁,而是被内部函数保留引用。 表现形式:每次调用返回的函数时,变量的值会持续累加或保持状态,不会重置。 应用场景:需要保存状态、累计计算等场景。后期可封装成闭包风格或面向对象风格。 十、递归函数递归是函数自己调用自己,必须设置退出条件,否则会无限循环导致栈溢出。 关键要点: - 递归调用时要用return返回,否则返回值会丢失
- 每次递归调用都要向最终出口靠近(如数值递增)
- 满足退出条件时立即返回,不再继续调用
实际应用:倍值计算、材料累计叠加等需要逐级计算的场景。使用不当容易造成死循环,需谨慎。 十一、参数与返回值的深入理解参数的本质:调用函数时,传入的值会自动赋值给函数定义的参数名,相当于在函数内部创建了同名的局部变量。 返回值的本质:函数执行完毕后,将结果传递回调用处。有返回值的函数可以看作"会说话的人",调用时能获取它说的话;无返回值的函数是"哑巴",只做事不回应。 使用建议: - 需要计算结果时用return返回,用变量接收
- 只需要执行动作用无需return
- 避免用全局变量传递结果,会造成内存污染
十二、实例
local function sumRecursive(n)
-- 退出条件:当n为1时,返回1
if n == 1 then
return 1
end
-- 递归调用:返回当前数加上前一个数的累加和
return n + sumRecursive(n - 1)
end
-- 计算1到100的累加和
local result = sumRecursive(100)
print(result) -- 输出: 5050
|