ฟังก์ชัน require
โหลดมอดูลภายนอกด้วย require และทำความเข้าใจการแคชมอดูล
ฟังก์ชัน require เป็นบทเรียน Lua Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Lua Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Lua Academy มีบทเรียนทั้งหมด 4 บทเรียน
การทำงานของ require
require(modname) โหลดและคืนค่าโมดูล โดยค้นหาไฟล์ .lua ใน package.path และไลบรารี C ใน package.cpath ผลลัพธ์จะถูกแคชไว้ใน package.loaded[modname] การเรียกครั้งถัดไปจึงคืนค่าที่แคชไว้โดยไม่ประมวลผลไฟล์ซ้ำ
-- First require: loads and executes math_utils.lua
local math_utils = require("math_utils")
-- Second require: returns cached value (file not re-run)
local math_utils2 = require("math_utils")
print(math_utils == math_utils2) -- true (same object)
print(package.loaded["math_utils"] == math_utils) -- trueค่าที่โมดูลคืน
ไฟล์โมดูลควรคืนค่าหนึ่งค่า โดยทั่วไปคือ ตารางของฟังก์ชัน ค่าที่คืนนี้คือสิ่งที่ require ส่งกลับให้ผู้เรียก หากไฟล์ไม่คืนค่าใดเลย (หรือคืนค่า true) require ก็จะคืนค่านั้น
-- mymodule.lua:
-- local M = {}
-- function M.hello() print("Hello from module!") end
-- return M
-- In main script:
local m = require("mymodule")
m.hello() -- Hello from module!
-- The module table is the interfaceการแคชใน package.loaded
package.loaded เป็นตารางที่จับคู่ชื่อโมดูลกับค่าที่โหลดแล้ว คุณสามารถกำหนดรายการด้วยตนเองเพื่อโหลดชุดจำลองล่วงหน้า หรือกำหนดเป็น nil เพื่อบังคับให้โหลดใหม่ (ไฟล์โมดูลจะถูกประมวลผลอีกครั้งเมื่อเรียก require ครั้งถัดไป)
-- Force reload by clearing cache
package.loaded["mymodule"] = nil
local fresh = require("mymodule") -- re-executes the file
-- Preload a mock for testing
package.loaded["db"] = {
query = function() return {} end,
close = function() end,
}
local db = require("db") -- gets the mockรูปแบบ package.path
package.path เป็นรายการรูปแบบที่คั่นด้วยอัฒภาค โดยตัวยึดตำแหน่ง ? จะถูกแทนที่ด้วยชื่อโมดูล (โดยจุดจะถูกแทนที่ด้วยตัวคั่นเส้นทาง) คุณสามารถเพิ่มไดเรกทอรีสำหรับค้นหาได้โดยเติมไว้ด้านหน้าของ package.path
print(package.path)
-- typically: ./?.lua;./?.luac;/usr/share/lua/5.4/?.lua;...
-- Add local lib directory
package.path = "./lib/?.lua;" .. package.path
-- Now require("utils") will look in ./lib/utils.luarequire เทียบกับ dofile และ loadfile
require: แคชและค้นหาใน package.path dofile(path): ประมวลผลไฟล์ทันทีโดยไม่แคช และรับเส้นทางโดยตรง loadfile(path): คอมไพล์แต่ไม่ประมวลผล และคืนค่าฟังก์ชัน ใช้ require สำหรับโมดูล และ dofile สำหรับสคริปต์ที่ใช้งานครั้งเดียว
-- dofile: no caching, direct path
dofile("./scripts/setup.lua")
-- loadfile: compile only, returns function
local fn, err = loadfile("./config.lua")
if fn then
local result = fn() -- execute when ready
end
-- require: best for modules
local json = require("json")ใช้จุดใน require เพื่ออ้างอิงไดเรกทอรี
ใช้จุดในชื่อโมดูลเพื่ออ้างอิงไฟล์ในไดเรกทอรีย่อย require("utils.string") จะจับคู่กับ utils/string.lua (โดยใช้ ? ในรูปแบบเส้นทาง) นี่คือวิธีจัดระเบียบไลบรารีที่มีหลายไฟล์
-- Directory structure:
-- lib/
-- utils/
-- string.lua
-- table.lua
-- init.lua
package.path = "./lib/?.lua;" .. package.path
local strUtils = require("utils.string") -- loads lib/utils/string.lua
local tblUtils = require("utils.table") -- loads lib/utils/table.luaผลข้างเคียงจากการเริ่มต้นโมดูล
ไฟล์โมดูลจะทำงานหนึ่งครั้งเมื่อถูก require ครั้งแรก โค้ดระดับบนสุดใด ๆ (ที่อยู่นอกฟังก์ชัน) จะทำงานในเวลาที่ require วิธีนี้มีประโยชน์สำหรับการเริ่มต้นเพียงครั้งเดียว แต่ควรระวัง เพราะผลข้างเคียง เช่น การเชื่อมต่อเครือข่ายหรือการดำเนินการกับไฟล์ จะทำงานในเวลานำเข้า
-- counter.lua:
-- local count = 0 -- initialized once on first require
-- local M = {}
-- function M.increment() count = count + 1 end
-- function M.get() return count end
-- return M
local c = require("counter")
c.increment()
c.increment()
print(c.get()) -- 2
local c2 = require("counter")
print(c2.get()) -- 2 (same instance, cached)การจัดการข้อผิดพลาดใน require
หากไฟล์โมดูลมีข้อผิดพลาดทางไวยากรณ์หรือยกข้อผิดพลาดระหว่างการโหลด require จะยกข้อผิดพลาดขึ้นมา ข้อความข้อผิดพลาดจะมีชื่อโมดูลและข้อผิดพลาดที่เกิดขึ้นภายในไฟล์ ใช้ pcall เพื่อจัดการความล้มเหลวในการโหลดโมดูลอย่างเหมาะสม
local ok, mod = pcall(require, "possibly_missing")
if not ok then
print("Module not available:", mod)
-- fall back to alternative or default implementation
mod = {feature = function() return "fallback" end}
end
print(mod.feature())package.preload
package.preload คือตารางที่คุณสามารถลงทะเบียนฟังก์ชันโหลดตามชื่อโมดูลได้ เมื่อมีการเรียกใช้ require("name") Lua จะตรวจสอบ preload ก่อน วิธีนี้ทำให้คุณลงทะเบียนโมดูลได้โดยไม่ต้องมีไฟล์ ซึ่งมีประโยชน์สำหรับ Lua แบบฝังตัวหรือการทดสอบ
package.preload["mymath"] = function()
return {
double = function(n) return n * 2 end,
triple = function(n) return n * 3 end,
}
end
local m = require("mymath")
print(m.double(5)) -- 10
print(m.triple(5)) -- 15การเรียกใช้ require แบบวนรอบ
การพึ่งพากันแบบวนรอบ (A ต้องใช้ B และ B ต้องใช้ A) จะได้รับการจัดการเพียงบางส่วน โดย Lua จะเก็บค่าแทนที่เป็น true ไว้ใน package.loaded ก่อนเรียกใช้โมดูล หาก B พยายามใช้ตารางของ A ที่ยังทำงานไม่เสร็จ อาจได้รับผลลัพธ์ที่ไม่ครบถ้วน ควรหลีกเลี่ยงการพึ่งพากันแบบวนรอบในการออกแบบโมดูล
-- a.lua: local b = require("b"); local M = {}; M.name = "A"; return M
-- b.lua: local a = require("a"); print("a.name:", a.name); return {}
-- When a.lua is loaded:
-- 1. a starts executing
-- 2. requires b -> b starts executing
-- 3. b requires a -> gets partial a (still loading!)
-- 4. a.name may be nil at step 3
print("Avoid circular requires in module design")ตรวจสอบความเข้าใจอย่างรวดเร็ว
จะเกิดอะไรขึ้นเมื่อคุณเรียกใช้ require("mod") เป็นครั้งที่สอง
สรุป: require
สรุป:
require(name)โหลดเพียงครั้งเดียวและเก็บไว้ในแคชที่package.loaded- ไฟล์โมดูลส่งคืนส่วนติดต่อสาธารณะของโมดูล (โดยปกติคือ table)
- ล้างค่า
package.loaded[name]เพื่อบังคับให้โหลดใหม่ - เพิ่มค่าใน
package.pathเพื่อกำหนดไดเรกทอรีค้นหาแบบกำหนดเอง - ใช้
package.preloadสำหรับโมดูลในหน่วยความจำ - หลีกเลี่ยงการพึ่งพากันแบบวนรอบ
คำถามที่พบบ่อย
บทเรียน “ฟังก์ชัน require” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ฟังก์ชัน require” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Lua Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Lua Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ฟังก์ชัน require”
โหลดมอดูลภายนอกด้วย require และทำความเข้าใจการแคชมอดูล คุณปฏิบัติ Lua Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Lua Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Lua Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “ฟังก์ชัน require” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Lua Academy นี้ได้ไหม
ได้ บทเรียน Lua Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ