Scrittura di un file di modulo
Crei un modulo restituendo una tabella di funzioni da un file .lua.
Scrittura di un file di modulo è una lezione Lua Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Lua Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Lua Academy include 4 lezioni in totale.
Il modello di modulo di base
Il modello standard per i moduli Lua consiste nel creare una tabella locale M, aggiungervi funzioni e valori e restituirla alla fine. La tabella costituisce l'API pubblica del modulo. Tutte le altre variabili locali del file sono private.
-- stringutils.lua
local M = {}
function M.trim(s)
return s:match("^%s*(.-)%s*$")
end
function M.split(s, sep)
local t = {}
for p in s:gmatch("[^"..sep.."]+") do t[#t+1]=p end
return t
end
return M
-- Usage:
-- local su = require("stringutils")
-- print(su.trim(" hello "))Stato privato
Le variabili dichiarate come local nel file del modulo sono private: chi lo utilizza non può accedervi. Le funzioni del modulo possono accedere allo stato privato come upvalue. Questo è il meccanismo di incapsulamento di Lua.
-- counter.lua
local M = {}
local count = 0 -- private state
function M.increment(n)
count = count + (n or 1)
end
function M.reset()
count = 0
end
function M.get()
return count
end
return MModulo con inizializzazione
Alcuni moduli richiedono un'inizializzazione, ad esempio per la configurazione o le connessioni. Inserisca il codice di inizializzazione a livello di modulo (all'inizio del file) oppure in una funzione esplicita M.init(). L'approccio a livello di modulo viene eseguito una volta al primo require; init() richiede una chiamata esplicita.
-- cache.lua
local M = {}
local store = {} -- initialized at load time
local hits = 0
local misses = 0
function M.get(key)
if store[key] ~= nil then
hits = hits + 1
return store[key]
end
misses = misses + 1
return nil
end
function M.set(key, val) store[key] = val end
function M.stats() return {hits=hits, misses=misses} end
return MModulo con classe
Un modulo può esportare una classe: una tabella con una funzione costruttrice. La tabella del modulo restituita contiene la funzione new() e può anche fungere da metatabella della classe.
-- point.lua
local Point = {}
Point.__index = Point
function Point.new(x, y)
return setmetatable({x=x, y=y}, Point)
end
function Point:distance(other)
local dx, dy = self.x-other.x, self.y-other.y
return math.sqrt(dx*dx + dy*dy)
end
function Point:__tostring()
return string.format("(%g,%g)", self.x, self.y)
end
return Point
-- Usage:
-- local Point = require("point")
-- local p = Point.new(3, 4)Costanti del modulo
Esporti le costanti aggiungendole alla tabella del modulo. Per convenzione, le costanti sono scritte in maiuscolo. Poiché Lua non dispone di const, tecnicamente gli utenti possono modificarle, ma il nome in maiuscolo segnala di non cambiarle.
-- colors.lua
local M = {}
M.RED = {r=255, g=0, b=0}
M.GREEN = {r=0, g=255, b=0}
M.BLUE = {r=0, g=0, b=255}
M.WHITE = {r=255, g=255, b=255}
M.BLACK = {r=0, g=0, b=0}
function M.toHex(c)
return string.format("#%02X%02X%02X", c.r, c.g, c.b)
end
return MVersionamento dei moduli
Includa un campo di versione nel modulo. Chi lo utilizza può controllare la versione per verificare la compatibilità. Usi il versionamento semantico (major.minor.patch).
-- mylib.lua
local M = {}
M._VERSION = "1.2.3"
M._NAME = "mylib"
M._DESCRIPTION = "My Lua library"
function M.hello(name)
return "Hello, " .. (name or "World") .. "!"
end
return M
-- Usage:
local mylib = require("mylib")
print(mylib._VERSION) -- 1.2.3
print(mylib.hello("Lua"))Sottomoduli
Le librerie di grandi dimensioni vengono suddivise in sottomoduli. Il modulo principale può richiedere e riesportare i sottomoduli, oppure ogni sottomodulo può essere usato indipendentemente. Organizzi i file in directory corrispondenti al percorso del modulo.
-- mylib/init.lua (loaded by require("mylib"))
local M = {}
M.strings = require("mylib.strings")
M.tables = require("mylib.tables")
M.math = require("mylib.math")
M._VERSION = "2.0.0"
return M
-- Users can require the whole library:
-- local mylib = require("mylib")
-- mylib.strings.trim(...)
-- Or individual sub-modules:
-- local strs = require("mylib.strings")Modulo con metatabella
Renda chiamabile un modulo assegnandogli una metatabella con __call. È utile per i moduli costituiti principalmente da funzioni ma dotati anche di utility: l'operazione principale è la chiamata, mentre le utility sono campi.
-- format.lua
local M = {}
setmetatable(M, {__call = function(_, fmt, ...)
return string.format(fmt, ...)
end})
function M.pad(s, width, char)
char = char or " "
return string.rep(char, math.max(0, width - #s)) .. s
end
return M
-- Usage:
-- local fmt = require("format")
-- print(fmt("%.2f", 3.14)) -- 3.14
-- print(fmt.pad("42", 5)) -- 42Caricamento differito dei sottomoduli
Usi __index per caricare i sottomoduli in modo differito, solo al primo accesso. Questo accelera l'avvio delle librerie di grandi dimensioni con molti sottomoduli.
-- biglib.lua
local M = {}
local submodules = {"strings", "tables", "math", "io"}
setmetatable(M, {
__index = function(t, k)
for _, name in ipairs(submodules) do
if name == k then
local mod = require("biglib." .. k)
rawset(t, k, mod)
return mod
end
end
return nil
end
})
return M
-- Loads biglib.strings only when accessed:
-- local lib = require("biglib")
-- lib.strings.trim(...)Modello per i test dei moduli
Aggiunga una funzione o un blocco di test in fondo al file del modulo, eseguito condizionalmente solo quando il file viene eseguito direttamente (e non quando viene richiesto). In questo modo i test unitari rimangono insieme al codice.
-- utils.lua
local M = {}
function M.clamp(v, lo, hi)
return math.max(lo, math.min(hi, v))
end
-- Self-test: only runs when executed directly
if debug.getinfo(2, "S") == nil then
-- Running as main script, not required
print("Testing clamp...")
assert(M.clamp(5, 0, 10) == 5)
assert(M.clamp(-1, 0, 10) == 0)
assert(M.clamp(15, 0, 10) == 10)
print("All tests passed!")
end
return MVerifica rapida
Qual è il modo standard per definire lo stato privato in un modulo Lua?
Riepilogo: scrivere moduli
Riepilogo:
- Modello:
local M = {} ... return M - Variabili locali nel file = private; campi di M = API pubblica
- Il codice a livello di modulo viene eseguito una volta al primo require
- Esporti le classi tramite un costruttore nella tabella del modulo
- Caricamento differito dei sottomoduli tramite
__index - Includa
_VERSIONper i controlli di compatibilità
Domande Frequenti
La lezione «Scrittura di un file di modulo» è gratuita?
Sì — il testo completo di «Scrittura di un file di modulo» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Lua Academy, passa a CoddyKit PRO. Il corso Lua Academy include 4 lezioni in totale.
Cosa imparerò in «Scrittura di un file di modulo»?
Crei un modulo restituendo una tabella di funzioni da un file .lua. Eserciti Lua Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Lua Academy?
Non è richiesta alcuna esperienza precedente. Lua Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.
Quanto tempo richiede la lezione «Scrittura di un file di modulo»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Lua Academy?
Sì. Ogni lezione Lua Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- La funzione require
- Scrittura di un file di modulo
- package.path e package.cpath
- Pattern e buone pratiche per i moduli