Modul dan pakej Lua


Modul adalah serupa dengan perpustakaan pakej Bermula dari Lua 5.1, Lua telah menambah mekanisme pengurusan modul standard, yang membolehkan anda meletakkan beberapa kod biasa dalam fail dan memanggilnya di tempat lain dalam bentuk. antara muka API Kondusif untuk penggunaan semula kod dan mengurangkan gandingan kod.

Modul Lua ialah jadual yang terdiri daripada elemen yang diketahui seperti pembolehubah dan fungsi, jadi mencipta modul adalah sangat mudah, hanya buat jadual, kemudian letakkan pemalar dan fungsi yang perlu dieksport ke dalamnya, dan akhirnya pulangkan meja Itu sahaja. Berikut ialah penciptaan modul modul tersuai.lua Format kod fail adalah seperti berikut:

-- 文件名为 module.lua
-- 定义一个名为 module 的模块
module = {}
 
-- 定义一个常量
module.constant = "这是一个常量"
 
-- 定义一个函数
function module.func1()
    io.write("这是一个公有函数!\n")
end
 
local function func2()
    print("这是一个私有函数!")
end
 
function module.func3()
    func2()
end
 
return module

Seperti yang dapat dilihat dari di atas, struktur modul adalah struktur jadual, jadi anda boleh mengendalikan. modul panggilan sama seperti elemen dalam jadual panggilan atau fungsi.

Fungsi2 di atas diisytiharkan sebagai pembolehubah tempatan bagi blok program, yang bermaksud ia mewakili fungsi persendirian dalam modul ini tidak boleh diakses dari luar dan mesti dipanggil melalui fungsi awam dalam modul.


memerlukan fungsi

Lua menyediakan fungsi yang dipanggil memerlukan untuk memuatkan modul. Untuk memuatkan modul, hanya panggilnya. Contohnya:

require("<模块名>")

atau

require "<模块名>"

Selepas melaksanakan keperluan, jadual yang terdiri daripada pemalar atau fungsi modul akan dikembalikan dan pembolehubah global yang mengandungi jadual juga akan ditakrifkan.

-- test_module.lua 文件
-- module 模块为上文提到到 module.lua
require("module")
 
print(module.constant)
 
module.func3()

Hasil pelaksanaan kod di atas ialah:

这是一个常量
这是一个私有函数!

Atau tentukan pembolehubah alias untuk modul yang dimuatkan untuk memudahkan panggilan:

-- test_module2.lua 文件
-- module 模块为上文提到到 module.lua
-- 别名变量 m
local m = require("module")
 
print(m.constant)
 
m.func3()

Hasil pelaksanaan kod di atas ialah:

这是一个常量
这是一个私有函数!

Mekanisme pemuatan

Untuk modul tersuai, fail modul tidak kira di mana direktori fail diletakkan. Fungsi memerlukan mempunyai strategi pemuatan laluan failnya sendiri muatkannya daripada fail Lua atau pustaka C.

memerlukan Laluan yang digunakan untuk mencari fail Lua disimpan dalam pakej pembolehubah global.path Apabila Lua dimulakan, pembolehubah persekitaran ini akan dimulakan dengan nilai pembolehubah persekitaran LUA_PATH. Jika pembolehubah persekitaran tidak ditemui, laluan lalai yang ditakrifkan pada masa penyusunan digunakan untuk permulaan.

Sudah tentu, jika tiada pembolehubah persekitaran LUA_PATH, anda juga boleh menyesuaikan tetapan dan membuka fail .profile dalam direktori akar pengguna semasa (cipta jika ia tidak wujud, atau buka fail .bashrc ), sebagai contoh, tukar "~/lua /" Tambah laluan kepada pembolehubah persekitaran LUA_PATH:

#LUA_PATH
export LUA_PATH="~/lua/?.lua;;"

Laluan fail dipisahkan dengan ";", dan dua terakhir ";;" bermakna yang baharu laluan diikuti oleh laluan lalai asal.

Seterusnya, kemas kini parameter pembolehubah persekitaran supaya ia berkuat kuasa serta-merta.

source ~/.profile

Anggapkan bahawa nilai package.path ialah:

/Users/dengjoe/lua/?.lua;./?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/lib/lua/5.1/?.lua;/usr/local/lib/lua/5.1/?/init.lua

Kemudian apabila require("module") dipanggil, ia akan cuba membuka direktori fail berikut untuk mencari sasaran.

/Users/dengjoe/lua/module.lua;
./module.lua
/usr/local/share/lua/5.1/module.lua
/usr/local/share/lua/5.1/module/init.lua
/usr/local/lib/lua/5.1/module.lua
/usr/local/lib/lua/5.1/module/init.lua

Jika fail sasaran ditemui, package.loadfile akan dipanggil untuk memuatkan modul. Jika tidak, ia pergi ke perpustakaan C.

Laluan fail yang dicari diperoleh daripada pakej pembolehubah global.cpath, dan pembolehubah ini dimulakan melalui pembolehubah persekitaran LUA_CPATH.

Strategi carian adalah sama seperti di atas, kecuali sekarang carian adalah untuk fail jenis so atau dll. Jika ia ditemui, require akan memuatkannya melalui package.loadlib.


Pakej C

Lua dan C mudah digabungkan Gunakan C untuk menulis pakej untuk Lua.

Tidak seperti pakej yang ditulis dalam Lua, pakej C mesti dimuatkan dan disambungkan terlebih dahulu sebelum digunakan Dalam kebanyakan sistem, cara paling mudah untuk melaksanakan ini adalah melalui mekanisme perpustakaan pautan dinamik.

Lua menyediakan semua fungsi pemautan dinamik dalam fungsi yang dipanggil loadlib. Fungsi ini mengambil dua parameter: laluan mutlak ke perpustakaan dan fungsi permulaan. Jadi contoh panggilan biasa adalah seperti berikut:

local path = "/usr/local/lua/lib/libluasocket.so"
local f = loadlib(path, "luaopen_socket")

Fungsi loadlib memuatkan pustaka yang ditentukan dan bersambung ke Lua Walau bagaimanapun, ia tidak membuka pustaka (iaitu, ia tidak memanggil fungsi inisialisasi). , ia mengembalikan fungsi pemulaan sebagai fungsi A Lua supaya kita boleh memanggilnya terus dalam Lua.

Jika ralat berlaku semasa memuatkan perpustakaan dinamik atau mencari fungsi permulaan, loadlib akan mengembalikan sifar dan mesej ralat. Kami boleh mengubah suai kod sebelumnya untuk mengesan ralat dan kemudian memanggil fungsi permulaan:

local path = "/usr/local/lua/lib/libluasocket.so"
-- 或者 path = "C:\windows\luasocket.dll",这是 Window 平台下
local f = assert(loadlib(path, "luaopen_socket"))
f()  -- 真正打开库

Secara amnya, kami menjangkakan pustaka keluaran binari mengandungi fail stub yang serupa dengan coretan kod sebelumnya. Anda boleh memasang binari perpustakaan dengan santai Letakkannya dalam direktori tertentu dan hanya ubah suai laluan sebenar perpustakaan binari yang sepadan dengan fail rintisan.

Tambah direktori di mana fail stub terletak pada LUA_PATH Selepas menetapkannya, anda boleh menggunakan fungsi memerlukan untuk memuatkan pustaka C.