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
endlocal quotient, remainder = divide_and_remainder(10, 3)
print(quotient, remainder)  -- 輸出 3 1

2. 變參函數(Variadic Function)

-- 使用 ... 接收任意數量參數
function sum(...)local total = 0for _, v in ipairs({...}) dototal = total + vendreturn total
endprint(sum(1,2,3,4))  -- 輸出 10

3. 函數作為返回值

function make_adder(x)return function(y)return x + yend
endlocal add5 = make_adder(5)
print(add5(3))  -- 輸出 8

三、進階特性

1. 閉包(Closure)

閉包是函數與其詞法環境的組合,可捕獲外部變量:

function counter()local count = 0return function()count = count + 1return countend
endlocal c = counter()
print(c())  -- 1
print(c())  -- 2

2. 尾調用優化(Tail Call Optimization)

尾調用不會增加調用棧深度,防止棧溢出:

function factorial(n, acc)acc = acc or 1if n == 0 then return acc endreturn factorial(n-1, n*acc)  -- 尾遞歸優化
endprint(factorial(5))  -- 輸出 120

3. 高階函數(Higher-Order Function)

函數作為參數或返回值:

-- map 函數
function map(t, fn)local result = {}for _, v in ipairs(t) dotable.insert(result, fn(v))endreturn result
endlocal 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
endgreet.__call = function(self, ...)return self.name .. ", " .. ...
endsetmetatable(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) + 1return func(...)end
endlocal function add(a, b)return a + b
endadd = hook(add)
add(1,2)
add(3,4)
print(call_counts[add])  -- 輸出 2

五、性能優化指南

1. 避免閉包濫用

-- 低效寫法:頻繁創建閉包
for i = 1, 1000 dolocal function fn() return i end  -- 每次循環都創建新閉包
end-- 優化寫法:使用局部變量捕獲
for i = 1, 1000 dolocal i_local = ilocal function fn() return i_local end
end

2. 內聯小函數

-- 頻繁調用的簡單函數可內聯
-- 優化前
local function square(x) return x*x end
for i = 1, 1e6 dosquare(i)
end-- 優化后
for i = 1, 1e6 dolocal 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)
endprint(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}
endlocal 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) dolistener(k, v)endend,add_listener = function(t, listener)table.insert(listeners, listener)end})
endlocal 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
endprint(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] thencache[key] = fn(...)endreturn cache[key]end
endlocal function process(a, b)return a + b
endlocal 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) dodefaults[k] = vendreturn defaults
endlocal cfg = config({height=400})
print(cfg.width, cfg.height)  -- 輸出 800 400

問題2:遞歸深度過大導致棧溢出

-- 尾遞歸優化版本
function fibonacci(n, a, b)a = a or 0b = b or 1if n == 0 then return a endif n == 1 then return b endreturn fibonacci(n-1, b, a+b)
endprint(fibonacci(1000))  -- 不會導致棧溢出

通過掌握這些函數特性與模式,你可以編寫出高效、靈活的 Lua 代碼。對于復雜場景,建議結合元編程和設計模式,同時注意性能優化細節。


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/75200.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/75200.shtml
英文地址,請注明出處:http://en.pswp.cn/web/75200.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用StockTV API對接印度金融市場數據全指南:K線、實時行情與IPO新股

一、印度金融市場數據特點 印度作為全球增長最快的主要經濟體之一,其金融市場具有以下顯著特征: 雙交易所體系:國家證券交易所(NSE)和孟買證券交易所(BSE)高流動性品種:Nifty 50指數成分股、銀行股等獨特交易機制:T2…

2021-10-26 C++繁忙通信兵

緣由繁忙的通訊兵,可以解決一下嗎-編程語言-CSDN問答 void 繁忙通信兵() {//緣由https://ask.csdn.net/questions/7544401?spm1005.2025.3001.5141int a 200, s1 8, s2 5, s3 45, p 0, n 0, c 0;std::cin >> n;while (a > n){a - s1 s2;if (a &l…

【Linux】進程控制:創建、終止、等待與替換全解析

文章目錄 前言一、重談進程創建二、進程終止2.1 正常終止的退出碼機制2.2 異常終止的信號機制2.3 進程常見的退出方法 三、進程等待:避免僵尸進程的關鍵3.1 進程等待的必要性3.2 進程等待的兩個系統調用接口3.2.1 wait()3.2.2 waitpid()區別 四、進程程序替換4.1 進…

基于Redis實現短信防轟炸的Java解決方案

基于Redis實現短信防轟炸的Java解決方案 前言 在當今互聯網應用中,短信驗證碼已成為身份驗證的重要手段。然而,這也帶來了"短信轟炸"的安全風險 - 惡意用戶利用程序自動化發送大量短信請求,導致用戶被騷擾和企業短信成本激增。本…

【后端開發】Spring MVC-常見使用、Cookie、Session

文章目錄 代碼總結初始化--RestController、RequestMapping傳遞參數單參數多參數 傳遞對象后端參數重命名(后端參數映射)--RequestParam必傳參數設置非必傳參數 傳遞數組傳遞集合傳遞JSON數據JSON語法JSON格式轉換JSON優點傳遞JSON對象 獲取URL中參數--P…

青少年編程考試 CCF GESP Python七級認證真題 2025年3月

Python 七級 2025 年 03 月 題號 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 答案 B C A B B A A B C A B B A B A 1 單選題(每題 2 分,共 30 分) 第 1 題 下列哪個選項是python中的關鍵字? A. function B. class C. method D. object…

Vue 框架組件間通信方式

組件間通信方式 不管是 vue2 還是 vue3,組件通信方式很重要,以下是常見的幾種通信方式: props:可以實現父子組件、子父組件、甚至兄弟組件通信自定義事件:可以實現子父組件通信全局事件總線 $bus:可以實現…

SpringBoot學生成績管理系統設計與實現

概述 幽絡源本次分享的基于SpringBoot的學生成績管理系統項目,采用主流的Java技術棧開發,實現了從學生信息管理到成績統計分析的全流程數字化管理。 主要內容 管理員功能模塊 ??學生信息管理??:維護學生基本信息檔案,支持…

青少年編程與數學 02-016 Python數據結構與算法 01課題、算法

青少年編程與數學 02-016 Python數據結構與算法 01課題、算法 一、算法的定義二、算法的設計方法1. 分治法2. 動態規劃法3. 貪心算法4. 回溯法5. 迭代法6. 遞歸法7. 枚舉法8. 分支定界法 三、算法的描述方法1. **自然語言描述**2. **流程圖描述**3. **偽代碼描述**4. **程序設計…

Java 實現冒泡排序:[通俗易懂的排序算法系列之二]

引言 大家好!歡迎來到我的排序算法系列第二篇。今天,我們將學習另一種非常基礎且廣為人知的排序算法——冒泡排序 (Bubble Sort)。 冒泡排序的名字非常形象,它模擬了水中氣泡上升的過程:較小(或較大)的元素會像氣泡一樣,通過不斷交換,逐漸“浮”到數組的一端。 什么是…

struct結構體、union聯合體和枚舉

目錄 一、結構體的聲明和使用 1.1 結構體正常聲明和創建 1.2 結構體特殊聲明 1.3 結構體的自引用 二、結構體內存對齊 2.1 對齊規則 2.2 #pragma修改 三、結構體傳參 四、結構體位段 4.1 位段內存分配 4.2 位段內存應用 五、結構體中的柔性數組概念 六、union聯合…

大模型本地部署系列(2) Ollama部署DeepSeek-R1

成功運行截圖 部署步驟 我們進入到ollama的官網: Ollama?ollama.com/?編輯 找到上方的Models ,然后點擊 此時會跳轉到模型列表頁面: 點擊 deepseek-r1 鏈接進去,此時我們會看到下拉框中有各個版本的大模型,越往后…

繪制動態甘特圖(以流水車間調度為例)

import matplotlib.pyplot as plt import matplotlib.animation as animation import numpy as np from matplotlib import cm# 中文字體配置(必須放在所有繪圖語句之前) plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] Fa…

PyTorch實現線性回歸的基礎寫法與封裝API寫法

目錄 1. 基礎寫法 1.1導包 2.2加載讀取數據 2.3原始數據可視化(畫圖顯示) 2.4線性回歸的(基礎)分解寫法 2.5定義訓練過程 2.PyTorch實現 線性回歸的封裝寫法(實際項目中的常用寫法) 2.1創建線性回歸模型 2.2定義損失函數 2.3定義優化器 2.4定義訓練過程 1…

python 常用的6個爬蟲第三方庫

Python中有非常多用于網絡數據采集的庫,功能非常強大,有的用于抓取網頁,有的用于解析網頁,這里介紹6個最常用的庫。 1. BeautifulSoup BeautifulSoup是最常用的Python網頁解析庫之一,可將 HTML 和 XML 文檔解析為樹形…

基于BP神經網絡的雜草智能識別系統(雜草識別、Python項目)

基于BP神經網絡的雜草智能識別系統 項目介紹 本項目是一個基于PyQt5和BP神經網絡的雜草智能識別系統。系統通過圖像處理和神經網絡技術, 能夠識別8種不同的雜草類別。用戶可以通過上傳圖片,系統會自動識別圖片中的雜草類別,并顯示識別結果和…

Python3筆記之號稱替代pip的uv包管理器

uv是什么? uv,這是一個由 Astral 團隊開發的極快速的Python包和項目管理工具,用Rust語言編寫。它集成了多種功能,旨在替代pip、pip-tools、pipx、poetry、pyenv、twine、virtualenv等多個工具,提供更高效、更全面的Py…

IT管理思路

甲方CIO和IT管理者-如何做好組織級IT能力提升_嗶哩嗶哩_bilibili

ChatGPT的GPT-4o創建圖像Q版人物提示詞實例展示

最近感覺GPT-4o發布的新功能真的強大,所以總結了一些提示詞分享給大家,大家可以去試試,玩法多多,可以用GPT-4o生成圖片,然后用可靈進行圖生視頻,就能去發布視頻了!接下來和筆者一起來試試&#…

Transformer Decoder Block的幾個優化方案

寫在前面 在大型語言模型(LLM)的演進浪潮中,Transformer 架構憑借其強大的并行計算能力和對長距離依賴的出色捕捉,奠定了核心地位。然而,標準的 Transformer Decoder Block 遵循著一種相對固定的模式:先進行自注意力(Self-Attention)捕捉上下文信息,再通過前饋神經網…