传奇手游风暴活动专区

  • 首页
  • 跨服动态
  • 行会战报
  • 装备图鉴
  • 2025-12-11 17:18:01

    Lua 函数使用的完整指南

    在 Lua 中,函数是一等公民(First-Class Citizen),这意味着函数可以像其他值一样被赋值、传递和操作。以下是 Lua 函数定义的完整指南,涵盖基础语法、高级特性、设计模式及性能优化。

    在Lua 中,函数定义的完整指南—目录

    一、基础语法1. 函数声明2. 匿名函数

    二、核心特性1. 多返回值2. 变参函数(Variadic Function)3. 函数作为返回值

    三、进阶特性1. 闭包(Closure)2. 尾调用优化(Tail Call Optimization)3. 高阶函数(Higher-Order Function)

    四、函数属性与元编程1. 函数属性2. 元表与函数钩子

    五、性能优化指南1. 避免闭包滥用2. 内联小函数3. 使用局部函数

    六、设计模式与最佳实践1. 策略模式2. 工厂模式3. 观察者模式

    七、调试与元信息1. 获取函数信息2. 函数重载(模拟)

    八、常见问题与解决方案问题1:函数参数过多时的处理问题2:递归深度过大导致栈溢出

    一、基础语法

    1. 函数声明

    -- 基础语法

    function add(a, b)

    return a + b

    end

    -- 调用

    print(add(3, 5)) -- 输出 8

    2. 匿名函数

    -- 无名称的函数(常用于回调)

    local function factorial(n)

    return n == 0 and 1 or n * factorial(n-1)

    end

    -- 将函数赋值给变量

    local square = function(x) return x * x end

    print(square(4)) -- 输出 16

    二、核心特性

    1. 多返回值

    function divide_and_remainder(a, b)

    return math.floor(a / b), a % b

    end

    local quotient, remainder = divide_and_remainder(10, 3)

    print(quotient, remainder) -- 输出 3 1

    2. 变参函数(Variadic Function)

    -- 使用 ... 接收任意数量参数

    function sum(...)

    local total = 0

    for _, v in ipairs({...}) do

    total = total + v

    end

    return total

    end

    print(sum(1,2,3,4)) -- 输出 10

    3. 函数作为返回值

    function make_adder(x)

    return function(y)

    return x + y

    end

    end

    local add5 = make_adder(5)

    print(add5(3)) -- 输出 8

    三、进阶特性

    1. 闭包(Closure)

    闭包是函数与其词法环境的组合,可捕获外部变量:

    function counter()

    local count = 0

    return function()

    count = count + 1

    return count

    end

    end

    local c = counter()

    print(c()) -- 1

    print(c()) -- 2

    2. 尾调用优化(Tail Call Optimization)

    尾调用不会增加调用栈深度,防止栈溢出:

    function factorial(n, acc)

    acc = acc or 1

    if n == 0 then return acc end

    return factorial(n-1, n*acc) -- 尾递归优化

    end

    print(factorial(5)) -- 输出 120

    3. 高阶函数(Higher-Order Function)

    函数作为参数或返回值:

    -- map 函数

    function map(t, fn)

    local result = {}

    for _, v in ipairs(t) do

    table.insert(result, fn(v))

    end

    return result

    end

    local numbers = {1,2,3,4}

    local squares = map(numbers, function(x) return x*x end)

    print(table.unpack(squares)) -- 输出 1 4 9 16

    四、函数属性与元编程

    1. 函数属性

    function greet(name)

    return "Hello, " .. name

    end

    greet.__call = function(self, ...)

    return self.name .. ", " .. ...

    end

    setmetatable(greet, { __call = function(f, name) return "Hi, "..name end })

    print(greet("Alice")) -- 输出 Hi, Alice

    2. 元表与函数钩子

    -- 统计函数调用次数

    local call_counts = {}

    local function hook(func)

    return function(...)

    call_counts[func] = (call_counts[func] or 0) + 1

    return func(...)

    end

    end

    local function add(a, b)

    return a + b

    end

    add = hook(add)

    add(1,2)

    add(3,4)

    print(call_counts[add]) -- 输出 2

    五、性能优化指南

    1. 避免闭包滥用

    -- 低效写法:频繁创建闭包

    for i = 1, 1000 do

    local function fn() return i end -- 每次循环都创建新闭包

    end

    -- 优化写法:使用局部变量捕获

    for i = 1, 1000 do

    local i_local = i

    local function fn() return i_local end

    end

    2. 内联小函数

    -- 频繁调用的简单函数可内联

    -- 优化前

    local function square(x) return x*x end

    for i = 1, 1e6 do

    square(i)

    end

    -- 优化后

    for i = 1, 1e6 do

    local x = i*i -- 直接展开计算

    end

    3. 使用局部函数

    -- 全局函数查找较慢

    function global_fn() end

    -- 优化:优先使用局部函数

    local local_fn = function() end

    六、设计模式与最佳实践

    1. 策略模式

    local strategies = {

    add = function(a,b) return a+b end,

    multiply = function(a,b) return a*b end

    }

    function calculate(operation, a, b)

    return (strategies[operation] or strategies.add)(a, b)

    end

    print(calculate("multiply", 3,4)) -- 输出 12

    2. 工厂模式

    local function create_user(name, age)

    return {

    name = name,

    age = age,

    greet = function(self)

    print("I'm", self.name)

    end

    }

    end

    local alice = create_user("Alice", 30)

    alice:greet() -- 输出 I'm Alice

    3. 观察者模式

    local function observable()

    local listeners = {}

    return setmetatable({}, {

    __newindex = function(t,k,v)

    rawset(t, k, v)

    for _, listener in ipairs(listeners) do

    listener(k, v)

    end

    end,

    add_listener = function(t, listener)

    table.insert(listeners, listener)

    end

    })

    end

    local obj = observable()

    obj:add_listener(function(key, value)

    print("Property changed:", key, value)

    end)

    obj.x = 10 -- 触发监听器输出

    七、调试与元信息

    1. 获取函数信息

    function example(a, b)

    return a + b

    end

    print(debug.getinfo(example).name) -- 输出 "example"

    print(debug.getupvalue(example, 1)) -- 查看闭包的上层变量(若有)

    2. 函数重载(模拟)

    local function overloaded(fn)

    local cache = {}

    return function(...)

    local key = table.concat({...}, "|")

    if not cache[key] then

    cache[key] = fn(...)

    end

    return cache[key]

    end

    end

    local function process(a, b)

    return a + b

    end

    local process_overloaded = overloaded(process)

    print(process_overloaded(1,2)) -- 计算并缓存

    print(process_overloaded(1,2)) -- 直接返回缓存结果

    八、常见问题与解决方案

    问题1:函数参数过多时的处理

    -- 使用表传递可选参数

    function config(options)

    local defaults = {width=800, height=600}

    for k, v in pairs(options) do

    defaults[k] = v

    end

    return defaults

    end

    local cfg = config({height=400})

    print(cfg.width, cfg.height) -- 输出 800 400

    问题2:递归深度过大导致栈溢出

    -- 尾递归优化版本

    function fibonacci(n, a, b)

    a = a or 0

    b = b or 1

    if n == 0 then return a end

    if n == 1 then return b end

    return fibonacci(n-1, b, a+b)

    end

    print(fibonacci(1000)) -- 不会导致栈溢出

    通过掌握这些函数特性与模式,你可以编写出高效、灵活的 Lua 代码。对于复杂场景,建议结合元编程和设计模式,同时注意性能优化细节。

    神仙酒价格表
    如何考取B2驾驶证
    装备图鉴

    友情链接:

    ©Copyright © 2022 传奇手游风暴活动专区 All Rights Reserved.