查看: 24|回复: 0

lua函数

[复制链接]

47

主题

53

回帖

1551

积分

金牌会员

积分
1551
发表于 2026-5-25 16:28:24 | 显示全部楼层 |阅读模式
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)表方法和对象方法
  • 表方法(Table Method)
定义:直接绑定在表上的函数,是 Lua 最基础的 “方法” 形式,本质是 “表的键值对,值为函数”。
  • 表是 Lua 最核心的数据结构,任何函数都可以作为表的一个字段(键),这个函数就称为 “表方法”;
  • 表方法不强制依赖 self,可独立调用,也可结合 self 使用。
  • 对象方法(Object Method)
定义:模拟面向对象编程时,给 “对象(本质还是表)” 绑定的、依赖 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岁









您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表