函数基础 #
一、函数定义 #
1.1 基本语法 #
lua
-- 基本语法
function name(parameters)
-- 函数体
return value
end
-- 示例
function greet()
print("Hello, Lua!")
end
greet() -- Hello, Lua!
1.2 函数定义方式 #
lua
-- 方式1:全局函数
function greet1()
print("Hello!")
end
-- 方式2:局部函数(推荐)
local function greet2()
print("Hello!")
end
-- 方式3:函数表达式
local greet3 = function()
print("Hello!")
end
-- 方式4:表方法
local obj = {}
function obj.method()
print("方法")
end
-- 方式5:冒号语法(自动传递 self)
function obj:method2()
print(self) -- self 是 obj
end
1.3 函数命名规范 #
lua
-- 推荐:小写字母,下划线分隔
local function calculate_sum(a, b)
return a + b
end
-- 返回布尔值的函数:is/has/can 前缀
local function is_valid(value)
return value ~= nil
end
local function has_permission(user, action)
return user.permissions[action] ~= nil
end
-- 获取值的函数:get 前缀
local function get_user_name(user)
return user.name or "Unknown"
end
-- 设置值的函数:set 前缀
local function set_user_name(user, name)
user.name = name
end
二、参数 #
2.1 基本参数 #
lua
-- 位置参数
local function add(a, b)
return a + b
end
print(add(1, 2)) -- 3
-- 参数不足时补 nil
local function greet(name, greeting)
greeting = greeting or "Hello"
print(greeting .. ", " .. name .. "!")
end
greet("Lua") -- Hello, Lua!
greet("Lua", "Hi") -- Hi, Lua!
2.2 默认参数 #
lua
-- 使用 or 设置默认值
local function create_config(options)
options = options or {}
local config = {
host = options.host or "localhost",
port = options.port or 8080,
timeout = options.timeout or 30
}
return config
end
local cfg = create_config()
print(cfg.host, cfg.port) -- localhost 8080
local cfg2 = create_config({host = "example.com", port = 3000})
print(cfg2.host, cfg2.port) -- example.com 3000
2.3 命名参数 #
lua
-- Lua 没有命名参数,但可以用表模拟
local function create_window(options)
local width = options.width or 800
local height = options.height or 600
local title = options.title or "Window"
print(string.format("窗口:%s (%dx%d)", title, width, height))
end
create_window {
title = "My App",
width = 1024,
height = 768
}
-- 窗口:My App (1024x768)
2.4 参数验证 #
lua
-- 类型检查
local function process(data)
if type(data) ~= "table" then
error("参数必须是表", 2)
end
if not data.name then
error("缺少 name 字段", 2)
end
return data.name
end
-- 使用 assert
local function divide(a, b)
assert(type(a) == "number", "a 必须是数字")
assert(type(b) == "number", "b 必须是数字")
assert(b ~= 0, "除数不能为 0")
return a / b
end
三、返回值 #
3.1 单返回值 #
lua
local function square(x)
return x * x
end
local result = square(5)
print(result) -- 25
3.2 多返回值 #
lua
-- 返回多个值
local function min_max(arr)
local min, max = arr[1], arr[1]
for _, v in ipairs(arr) do
if v < min then min = v end
if v > max then max = v end
end
return min, max
end
local minimum, maximum = min_max({3, 1, 4, 1, 5, 9})
print(minimum, maximum) -- 1 9
-- 忽略部分返回值
local min, _ = min_max({1, 2, 3})
print(min) -- 1
3.3 返回值的使用 #
lua
-- 作为函数参数
local function get_coords()
return 10, 20
end
local function distance(x, y)
return math.sqrt(x * x + y * y)
end
print(distance(get_coords())) -- 22.36...
-- 在表中使用
local point = {get_coords()}
print(point[1], point[2]) -- 10 20
-- 多重赋值
local x, y, z = get_coords(), 30
print(x, y, z) -- 10 20 30
-- 注意:只有最后一个表达式会展开多个返回值
local a, b, c = get_coords()
print(a, b, c) -- 10 20 nil
3.4 返回表 #
lua
-- 返回多个命名值
local function get_user_info(id)
return {
id = id,
name = "User" .. id,
email = "user" .. id .. "@example.com",
active = true
}
end
local user = get_user_info(1)
print(user.name, user.email)
四、函数调用 #
4.1 基本调用 #
lua
-- 普通调用
function add(a, b)
return a + b
end
print(add(1, 2)) -- 3
-- 单参数时可以省略括号
print "Hello" -- Hello
print [[Hello World]] -- Hello World
-- 表参数可以省略括号
local function process(options)
print(options.name)
end
process {name = "Lua"} -- Lua
4.2 方法调用 #
lua
local obj = {
name = "Object",
value = 42
}
-- 点语法
function obj.get_name(self)
return self.name
end
print(obj.get_name(obj)) -- Object
-- 冒号语法(自动传递 self)
function obj:get_value()
return self.value
end
print(obj:get_value()) -- 42
-- 冒号定义和调用
obj:method = function(self)
print(self.name)
end
obj:method() -- Object
4.3 链式调用 #
lua
local Calculator = {}
Calculator.__index = Calculator
function Calculator:new()
return setmetatable({value = 0}, self)
end
function Calculator:add(n)
self.value = self.value + n
return self
end
function Calculator:sub(n)
self.value = self.value - n
return self
end
function Calculator:result()
return self.value
end
-- 链式调用
local calc = Calculator:new()
local result = calc:add(10):sub(3):add(5):result()
print(result) -- 12
五、递归函数 #
5.1 基本递归 #
lua
-- 阶乘
local function factorial(n)
if n <= 1 then
return 1
end
return n * factorial(n - 1)
end
print(factorial(5)) -- 120
-- 斐波那契
local function fib(n)
if n <= 1 then
return n
end
return fib(n - 1) + fib(n - 2)
end
print(fib(10)) -- 55
5.2 尾递归 #
lua
-- 普通递归(可能栈溢出)
local function sum(n)
if n <= 0 then
return 0
end
return n + sum(n - 1) -- 不是尾递归
end
-- 尾递归优化
local function sum_tail(n, acc)
acc = acc or 0
if n <= 0 then
return acc
end
return sum_tail(n - 1, acc + n) -- 尾递归
end
print(sum_tail(10000)) -- 不会栈溢出
5.3 递归应用 #
lua
-- 遍历嵌套表
local function deep_print(t, indent)
indent = indent or ""
for k, v in pairs(t) do
if type(v) == "table" then
print(indent .. k .. ":")
deep_print(v, indent .. " ")
else
print(indent .. k .. ": " .. tostring(v))
end
end
end
-- 深拷贝
local function deep_copy(t)
if type(t) ~= "table" then
return t
end
local copy = {}
for k, v in pairs(t) do
copy[deep_copy(k)] = deep_copy(v)
end
return copy
end
六、匿名函数 #
6.1 基本用法 #
lua
-- 匿名函数
local greet = function(name)
print("Hello, " .. name)
end
greet("Lua")
-- 作为参数
local arr = {3, 1, 4, 1, 5}
table.sort(arr, function(a, b)
return a > b
end)
print(table.concat(arr, ", ")) -- 5, 4, 3, 1, 1
-- 立即执行函数
local result = (function(x)
return x * x
end)(5)
print(result) -- 25
6.2 高阶函数 #
lua
-- map 函数
local function map(arr, func)
local result = {}
for i, v in ipairs(arr) do
result[i] = func(v, i)
end
return result
end
local doubled = map({1, 2, 3, 4, 5}, function(x)
return x * 2
end)
print(table.concat(doubled, ", ")) -- 2, 4, 6, 8, 10
-- filter 函数
local function filter(arr, func)
local result = {}
for _, v in ipairs(arr) do
if func(v) then
table.insert(result, v)
end
end
return result
end
local evens = filter({1, 2, 3, 4, 5}, function(x)
return x % 2 == 0
end)
print(table.concat(evens, ", ")) -- 2, 4
-- reduce 函数
local function reduce(arr, func, initial)
local acc = initial
for _, v in ipairs(arr) do
acc = func(acc, v)
end
return acc
end
local sum = reduce({1, 2, 3, 4, 5}, function(acc, v)
return (acc or 0) + v
end, 0)
print(sum) -- 15
七、函数作为值 #
7.1 函数赋值 #
lua
-- 函数可以赋值给变量
local f = print
f("Hello") -- Hello
-- 函数可以存储在表中
local operations = {
add = function(a, b) return a + b end,
sub = function(a, b) return a - b end,
mul = function(a, b) return a * b end,
div = function(a, b) return a / b end
}
print(operations.add(10, 5)) -- 15
print(operations.mul(10, 5)) -- 50
7.2 函数作为参数 #
lua
-- 回调函数
local function process_async(data, callback)
-- 模拟异步处理
local result = data * 2
callback(result)
end
process_async(10, function(result)
print("结果:" .. result)
end)
-- 策略模式
local function calculate(a, b, strategy)
return strategy(a, b)
end
print(calculate(10, 5, operations.add)) -- 15
print(calculate(10, 5, operations.mul)) -- 50
7.3 函数作为返回值 #
lua
-- 工厂函数
local function create_multiplier(factor)
return function(x)
return x * factor
end
end
local double = create_multiplier(2)
local triple = create_multiplier(3)
print(double(5)) -- 10
print(triple(5)) -- 15
-- 条件返回函数
local function get_handler(type)
if type == "json" then
return function(data)
return '{"data":"' .. data .. '"}'
end
elseif type == "xml" then
return function(data)
return "<data>" .. data .. "</data>"
end
else
return function(data)
return data
end
end
end
local handler = get_handler("json")
print(handler("hello")) -- {"data":"hello"}
八、实用示例 #
8.1 防抖函数 #
lua
local function debounce(func, delay)
local timer = nil
return function(...)
local args = {...}
if timer then
timer = nil -- 取消之前的计时器
end
timer = setTimeout(function() -- 假设有 setTimeout
func(table.unpack(args))
end, delay)
end
end
8.2 记忆化 #
lua
local function memoize(func)
local cache = {}
return function(...)
local key = table.concat({...}, ",")
if cache[key] == nil then
cache[key] = func(...)
end
return cache[key]
end
end
local memo_fib = memoize(function(n)
if n <= 1 then return n end
return memo_fib(n - 1) + memo_fib(n - 2)
end)
print(memo_fib(40)) -- 快速计算
8.3 函数组合 #
lua
local function compose(...)
local funcs = {...}
return function(x)
local result = x
for i = #funcs, 1, -1 do
result = funcs[i](result)
end
return result
end
end
local double = function(x) return x * 2 end
local add_one = function(x) return x + 1 end
local square = function(x) return x * x end
local composed = compose(square, add_one, double)
print(composed(3)) -- ((3 * 2) + 1) ^ 2 = 49
九、总结 #
本章介绍了 Lua 函数的基础知识:
- 函数定义:多种定义方式
- 参数:位置参数、默认参数、命名参数
- 返回值:单返回值、多返回值
- 函数调用:普通调用、方法调用、链式调用
- 递归:基本递归、尾递归优化
- 匿名函数:作为参数和返回值
- 高阶函数:map、filter、reduce
函数是 Lua 编程的核心概念。下一章,我们将深入学习闭包和高阶函数。
最后更新:2026-03-27