|
|
|
Lua 函数有两种定义形式,核心语法是 function 函数名(参数) ... end,结束必须用 end 界定代码块。 函数声明
Lua复制代码
-- 方式1:标准定义(全局函数)function add(a, b) return a + b -- 返回值,可多个end-- 方式2:标准定义(局部函数)local function add1(a, b) return a + b -- 返回值,可多个end-- 方式3:赋值式定义(更灵活,可定义局部函数)local sub = function(a, b) return a - bend-- 调用函数(和其他语言一致)local sum = add(3, 5)local sum1 = add1(3, 5)local diff = sub(10, 4)print(sum, sum1, diff) -- 输出:8 8 6函数参数Lua 不检查调用时的参数个数,参数不匹配时会自动补 nil 或忽略多余参数; 参数不匹配
Lua复制代码
-- 示例:参数个数不匹配function test(a, b) print(a, b)endtest(1) -- 输出:1 nil(第二个参数补 nil)test(1, 2, 3) -- 输出:1 2(第三个参数被忽略)默认参数:手动实现(Lua 无原生默认参数)
Lua复制代码
-- 示例:给参数设置默认值function greet(name) -- 如果 name 是 nil,赋值为 "游客" name = name or "游客" print("你好," .. name)endgreet() -- 输出:你好,游客greet("张三") -- 输出:你好,张三可变参数:接收任意个数的参数 用 ...(三点)表示可变参数,可通过 {...} 转为 table 遍历,或用 select() 获取参数个数 / 指定参数。
Lua复制代码
-- 示例1:求和任意个数的数字function sum(...) local args = {...} -- 把可变参数转为 table local total = 0 for _, v in ipairs(args) do total = total + v end return totalendprint(sum(1,2,3)) -- 输出:6print(sum(10,20,30)) -- 输出:60-- 示例2:用 select 获取参数信息function test(...) print(select("#", ...)) -- 获取参数个数:输出 3 print(select(2, ...)) -- 获取第 2 个及之后的参数:输出 2 3endtest(1,2,3)函数值Lua 函数可以返回多个值,调用时可接收全部或部分返回值,这是和很多语言的重要区别。
Lua复制代码
-- 定义返回多个值的函数function get_user() return "张三", 20, "男" -- 返回 3 个值end-- 接收全部返回值local name, age, gender = get_user()print(name, age, gender) -- 输出:张三 20 男-- 只接收部分返回值(多余的会被忽略)local name_only = get_user()print(name_only) -- 输出:张三-- 忽略某个返回值(用 _ 占位)local _, age_only = get_user()print(age_only) -- 输出:20函数的高级用法函数作为值Lua 中函数是 “第一类值”,可以赋值给变量、作为参数传递、作为 table 的元素,这是实现回调、闭包的基础。
Lua复制代码
function add(a, b) return a + bendfunction sub(a, b) return a - bend-- 1. 函数赋值给变量local f = addprint(f(4,5)) -- 输出:9-- 2. 函数作为 table 的元素(模拟对象方法)local user = { name = "李四", say = function(self) print("我是" .. self.name) end}user:say() -- 输出:我是李四(冒号自动传 self)-- 3. 函数作为参数(回调函数)function calculate(a, b, func) return func(a, b)endlocal result = calculate(10, 5, sub) -- 传入 sub 函数print(result) -- 输出:5闭包闭包是 “可以访问外部作用域变量的函数”,即使外部作用域已结束,闭包仍能访问这些变量,是 Lua 实现私有变量、工厂函数的核心。
Lua复制代码
-- 示例:工厂函数,生成累加器function create_counter(init) local count = init or 0 -- 外部作用域变量 -- 闭包函数:访问外部的 count return function() count = count + 1 return count endend-- 创建两个独立的累加器local counter1 = create_counter(0)local counter2 = create_counter(10)print(counter1()) -- 输出:1print(counter1()) -- 输出:2print(counter2()) -- 输出:11print(counter2()) -- 输出:12递归函数可以调用自身(递归),需注意设置终止条件,避免死循环。
Lua复制代码
-- 示例:递归计算阶乘function factorial(n) if n == 1 then -- 终止条件 return 1 end return n * factorial(n-1) -- 递归调用endprint(factorial(5)) -- 输出:120(5*4*3*2*1)表方法和对象方法定义:直接绑定在表上的函数,是 Lua 最基础的 “方法” 形式,本质是 “表的键值对,值为函数”。 - 表是 Lua 最核心的数据结构,任何函数都可以作为表的一个字段(键),这个函数就称为 “表方法”;
- 表方法不强制依赖 self,可独立调用,也可结合 self 使用。
定义:模拟面向对象编程时,给 “对象(本质还是表)” 绑定的、依赖 self 访问对象属性的表方法。 - Lua 中 “对象” 是通过表模拟的(表包含属性 + 方法),“对象方法” 就是这个模拟对象的方法;
- 必须依赖 self(指向对象本身),用于访问对象的属性,是表方法的 “面向对象化” 用法。
Lua复制代码
-- 定义一个工具表,存放通用函数(纯表方法)local utils = {}-- 表方法1:无参数,纯功能utils.print_hello = function() print("Hello, Lua!")end-- 表方法2:有参数,处理外部数据utils.add = function(a, b) return a + bend-- 调用:只用 . 调用,无需 selfutils.print_hello() -- 输出:Hello, Lua!print(utils.add(1, 2)) -- 输出:3把表当作 “对象”,表中既有属性(如 name/age),又有方法(依赖 self 访问属性),这就是 “对象方法”:
Lua复制代码
-- 把表当作“对象”,包含属性和方法local person = { name = "fengfeng", age = 21}-- 定义对象方法:必须接收 self(指向对象本身),访问对象属性function person:say_hello() -- 定义时用 :,自动加 self 参数 print("我是" .. self.name .. ",今年" .. self.age .. "岁")end-- 定义对象方法:修改对象属性function person:grow_up() self.age = self.age + 1 print(self.name .. "长大了,现在" .. self.age .. "岁")end-- 调用对象方法:用 :,自动传 self(即 person)person:say_hello() -- 输出:我是fengfeng,今年21岁person:grow_up() -- 输出:fengfeng长大了,现在22岁
|
|