婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > 解析Lua中的全局環境、包、模塊組織結構

解析Lua中的全局環境、包、模塊組織結構

熱門標簽:衡水外呼線路解決 杞縣地圖標注app 昆明電話外呼系統好么 免費門店地圖標注注冊入駐 陜西便宜電銷機器人軟件 外呼系統一天耗費多少流量 艾比利外呼系統 海口智能語音電銷機器人好用嗎 電話機器人每天搜索多少次

模塊就是一個程序庫,而包是一系列模塊。Lua中可以通過require來加載模塊,然后得到一個全局變量表示一個table。Lua將其所有的全局變量保存在一個被稱為“環境”的常規table中。本文首先介紹環境的一些實用技術,然后介紹如何引用模塊及編寫模塊的基本方法。

1. 環境
Lua將環境table保存在一個全局變量_G中,可以對其訪問和設置。有時我們想操作一個全局變量,而它的名稱卻存儲在另一個變量中,或者需要通過運行時的計算才能得到,可以通過value = _G[varname]來獲得動態名字的全局變量。

關于“環境”的一大問題是它是全局的,任何對它的修改都會影響程序的所有部分。Lua 5允許每個函數擁有一個子集的環境來查找全局變量,可以通過setfenv來改變一個函數的環境,第一個參數若是1則表示當前函數,2則表示調用當前函數的函數(依次類推),第二個參數是一個新的環境table。

a = 1
setfenv(1, {})
print(a) -- 會報錯,print是一個nil。這是因為一旦改變環境,所有的全局訪問都會使用新的table

為了避免上述問題,可以使用setfenv(1, {_G = _G})將原來的環境保存起來,然后用_G.print來引用。另一種組裝新環境的方法是使用繼承,下面的代碼新環境從源環境中繼承了print和a,任何賦值都發生在新的table中。

a = 1
local newgt = {}
setmetatable(newgt, {__index = _G})
setfenv(1, newgt)
print(a)

2. 模塊與包
2.1 調用模塊

要調用模塊mod中的foo方法,可以用require函數來加載,如:

require "mod"
mod.foo()
-- 或者
local m = require "mod"
m.foo()

require函數的行為: (關于require使用的路徑查找策略不贅述)
在package.loaded這個table中檢查模塊是否已加載
=> 已加載,就返回相應的值(可見一個模塊只會加載一次)
=> 未加載,就試著在package.preload中查詢傳入的模塊名
===> 找到一個函數,就以該函數作為模塊的加載器
===> 找不到,則嘗試從Lua文件或C程序庫中加載模塊
=====> 找到Lua文件,通過loadfile來加載文件
=====> 找到C程序庫,通過loadlib來加載文件

2.2 使用環境

下面的代碼說明了如何用環境來創建一個復數(complex)模塊:

-- 模塊設置
local modname = "complex"
local M = {}
_G[modname] = M
package.loaded[modname] = M

-- 聲明模塊從外界所需的所有東西
local _G = _G -- 保留舊環境的引用,使用時需要像_G.print這樣用
local io = io

-- 運行這句之后環境就變了
setfenv(1, M)

function new(r, i) return {r=r, i=i} end

function add(c1, c2)
  return new(c1.r + c2.r, c1.i + c2.i)
end

這樣聲明函數add時,就成為了complex.add,調用同一模塊的其他函數也不需要加前綴。

2.3 module函數

Lua 5.1提供了一個新函數module,囊括了上面一系列定義環境的功能。在開始編寫一個模塊時,可以直接用module("modname", package.seeall)來取代前面的設置代碼。在一個模塊文件開頭有這句調用后,后續所有代碼都不需要限定模塊名和外部名字,同樣也不需要返回模塊table了。

2.4 子模塊與包

Lua支持具有層級的模塊名,用一個點來分隔名稱中的層級。例如一個模塊名為mod.sub,就是mod的一個子模塊。一個包(package)就是一個完整的模塊樹,它是Lua中發型的單位。注意,當搜索一個子模塊文件時,require會把點號當做目錄分隔符來搜索,也就是說調用require "a.b"會嘗試打開./a/b.lua,/usr/local/lua/a/b.lua,/usr/local/lua/a/b/init.lua。通過這種加載策略,可以將包的所有模塊組織到一個目錄中。

2.5 以自定義方式加載 lua 模塊
從 Lua 5.1 以后,Lua 有了標準的模塊管理庫。所以所有的模塊加載都是通過 require 來完成。 require 的設計是頗具擴展性的,它會從若干個定義好的 loader 中逐個嘗試加載新的模塊。系統庫中提供了四個 loader ,分別實現已加載模塊,Lua 模塊,和 C 擴展模塊(用了兩個 loader 來實現 C 擴展模塊的加載)。這些 loader 以 CFunction 的形式放在 require 的環境中的一個 table 里。

如果我們想改變 lua 模塊的加載形式,只需要替換或增加一個新的 loader 就可以了。

要做的只需要模仿 loadlib.c 中的 loader_Lua 函數做一個自己的實現,比如在我們的項目中,就允許從自定義格式數據包中,加載一個被加密過的 Lua 代碼文件。然后寫幾行 C 代碼,獲得 require 的環境(使用 lua_getfenv ),然后取出其中 "loaders" 這個 table ,把新的自定義 loader 插入到 index 2 的地方。

具體的代碼就不詳述了,仔細閱讀一下 ll_require 的實現(在 loadlib.c 中)就很容易明白。我們的整個工作從分析到實現沒有超過兩個小時,這真是得益于 Lua 良好的設計啊 :D 甚至如果你想從一個網絡連接的數據流中加載 Lua 模塊,或是通過 http/ftp 協議下載,也是行的通的吧。

您可能感興趣的文章:
  • 解決nginx+lua搭建文件上傳下載服務問題
  • Lua在windows下的安裝及環境配置
  • 安裝Nginx+Lua開發環境
  • Mac平臺中編譯安裝Lua運行環境及Hello Lua實例
  • Lua在各個操作系統中的開發環境配置教程
  • Lua的函數環境、包實例講解
  • linux系統安裝Nginx Lua環境
  • 如何使用Vim搭建Lua開發環境詳解

標簽:南京 昌都 宿遷 營口 西寧 臨滄 泰安 海口

巨人網絡通訊聲明:本文標題《解析Lua中的全局環境、包、模塊組織結構》,本文關鍵詞  解析,Lua,中的,全局,環境,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《解析Lua中的全局環境、包、模塊組織結構》相關的同類信息!
  • 本頁收集關于解析Lua中的全局環境、包、模塊組織結構的相關信息資訊供網民參考!
  • 推薦文章
    主站蜘蛛池模板: 马关县| 千阳县| 冀州市| 永济市| 连山| 应城市| 广平县| 阿克陶县| 钦州市| 荣昌县| 华蓥市| 绥滨县| 沽源县| 瑞金市| 中方县| 桓台县| 蕲春县| 龙南县| 宁河县| 梓潼县| 基隆市| 正定县| 屯门区| 调兵山市| 清原| 吉隆县| 沙河市| 搜索| 台州市| 图们市| 内黄县| 栾川县| 南丰县| 如东县| 华安县| 抚州市| 营口市| 林口县| 浠水县| 京山县| 馆陶县|