lua函数
Lua 函数有两种定义形式,核心语法是 function 函数名(参数) ... end,结束必须用 end 界定代码块。 函数声明 -- 方式1:标准定义(全局函数) function add(

lua函数

发布时间:2026-01-08 (2026-01-08)

Lua 函数有两种定义形式,核心语法是 function 函数名(参数) ... end,结束必须用 end 界定代码块。

函数声明

-- 方式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 - b
end

-- 调用函数(和其他语言一致)
local sum = add(3, 5)
local sum1 = add1(3, 5)
local diff = sub(10, 4)
print(sum, sum1, diff)  -- 输出:8 8 6

函数参数

Lua 不检查调用时的参数个数,参数不匹配时会自动补 nil 或忽略多余参数;

参数不匹配

-- 示例:参数个数不匹配
function test(a, b)
    print(a, b)
end

test(1)        -- 输出:1 nil(第二个参数补 nil)
test(1, 2, 3)  -- 输出:1 2(第三个参数被忽略)

默认参数:手动实现(Lua 无原生默认参数)

-- 示例:给参数设置默认值
function greet(name)
    -- 如果 name 是 nil,赋值为 "游客"
    name = name or "游客"
    print("你好," .. name)
end

greet()        -- 输出:你好,游客
greet("张三")  -- 输出:你好,张三

可变参数:接收任意个数的参数

用 ...(三点)表示可变参数,可通过 {...} 转为 table 遍历,或用 select() 获取参数个数 / 指定参数。

-- 示例1:求和任意个数的数字
function sum(...)
    local args = {...}  -- 把可变参数转为 table
    local total = 0
    for _, v in ipairs(args) do
        total = total + v
    end
    return total
end

print(sum(1,2,3))    -- 输出:6
print(sum(10,20,30)) -- 输出:60

-- 示例2:用 select 获取参数信息
function test(...)
    print(select("#", ...))  -- 获取参数个数:输出 3
    print(select(2, ...))    -- 获取第 2 个及之后的参数:输出 2 3
end
test(1,2,3)

函数值

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 的元素,这是实现回调、闭包的基础。

function add(a, b)
    return a + b
end
function sub(a, b)
    return a - b
end

-- 1. 函数赋值给变量
local f = add
print(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)
end
local result = calculate(10, 5, sub)  -- 传入 sub 函数
print(result)  -- 输出:5

闭包

闭包是 “可以访问外部作用域变量的函数”,即使外部作用域已结束,闭包仍能访问这些变量,是 Lua 实现私有变量、工厂函数的核心。

-- 示例:工厂函数,生成累加器
function create_counter(init)
    local count = init or 0  -- 外部作用域变量
    -- 闭包函数:访问外部的 count
    return function()
        count = count + 1
        return count
    end
end

-- 创建两个独立的累加器
local counter1 = create_counter(0)
local counter2 = create_counter(10)

print(counter1())  -- 输出:1
print(counter1())  -- 输出:2
print(counter2())  -- 输出:11
print(counter2())  -- 输出:12

递归

函数可以调用自身(递归),需注意设置终止条件,避免死循环。

-- 示例:递归计算阶乘
function factorial(n)
    if n == 1 then  -- 终止条件
        return 1
    end
    return n * factorial(n-1)  -- 递归调用
end

print(factorial(5))  -- 输出:120(5*4*3*2*1)

表方法和对象方法

  1. 表方法(Table Method)

定义:直接绑定在表上的函数,是 Lua 最基础的 “方法” 形式,本质是 “表的键值对,值为函数”。

  • 表是 Lua 最核心的数据结构,任何函数都可以作为表的一个字段(键),这个函数就称为 “表方法”;
  • 表方法不强制依赖 self,可独立调用,也可结合 self 使用。
  1. 对象方法(Object Method)

定义:模拟面向对象编程时,给 “对象(本质还是表)” 绑定的、依赖 self 访问对象属性的表方法。

  • Lua 中 “对象” 是通过表模拟的(表包含属性 + 方法),“对象方法” 就是这个模拟对象的方法;
  • 必须依赖 self(指向对象本身),用于访问对象的属性,是表方法的 “面向对象化” 用法。
-- 定义一个工具表,存放通用函数(纯表方法)
local utils = {}

-- 表方法1:无参数,纯功能
utils.print_hello = function()
    print("Hello, Lua!")
end

-- 表方法2:有参数,处理外部数据
utils.add = function(a, b)
    return a + b
end

-- 调用:只用 . 调用,无需 self
utils.print_hello() -- 输出:Hello, Lua!
print(utils.add(1, 2)) -- 输出:3

把表当作 “对象”,表中既有属性(如 name/age),又有方法(依赖 self 访问属性),这就是 “对象方法”:

-- 把表当作“对象”,包含属性和方法
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岁