日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

require函数

發布時間:2023/12/20 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 require函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

require函數

https://www.cnblogs.com/sylvan/p/8592472.html

Lua筆記——4.Package

目錄

  • require函數
    • 創建模塊
    • 調用模塊
  • module函數
    • 簡化module的創建
    • Lua5.1 & setfenv (f, table)
    • Lua5.1 & module(...)
    • Lua5.2之后

?


module簡介

Lua 5.1 加入模塊管理機制module,類似于Java的packages、C++的namespaces,可以通過require用于加載模塊,module用于創建模塊。require加載一個自定義或者第三方的module,然后便得到了一個全局變量,表示一個table。

Lua 5.2 之后則去掉了module創建模塊的函數,僅保留requir加載函數在全局環境

回到頂部

require函數

創建模塊

在Lua中創建一個模塊最簡單的方法:創建一個table,并將所有需要導出的函數放入其中,最后返回這個table,相當于將導出的函數作為table的一個字段。

創建一個簡單模塊,代碼如下:

--file: simpleMod.lualocal _Mod = {}_Mod._Mod = _Modfunction _Mod:New(name)local mod = {}mod.Name = name or "Default Name"mod._VERSION = 0.01return setmetatable(mod , {__index = self}) endfunction _Mod:Update()self._VERSION = self._VERSION + 0.01return self._VERSION endreturn _Mod

調用模塊

require (modname)

Loads the given module. The function starts by looking into the package.loaded table to determine whether modname is already loaded. If it is, then require returns the value stored at package.loaded[modname]. Otherwise, it tries to find a loader for the module.

To find a loader, require is guided by the package.loaders array.(package.loaders array:A table used by require to control how to load modules.) By changing this array, we can change how require looks for a module. The following explanation is based on the default configuration for package.loaders.

First require queries package.preload[modname].(A table to store loaders for specific modules) If it has a value, this value (which should be a function) is the loader. Otherwise require searches for a Lua loader using the path stored in package.path. If that also fails, it searches for a C loader using the path stored in package.cpath. If that also fails, it tries an all-in-one loader (see package.loaders).

Once a loader is found, require calls the loader with a single argument, modname. If the loader returns any value, require assigns the returned value to package.loaded[modname]. If the loader returns no value and has not assigned any value to package.loaded[modname], then require assigns true to this entry. In any case, require returns the final value of package.loaded[modname].

If there is any error loading or running the module, or if it cannot find any loader for the module, then require signals an error.

require函數的調用形式為require "模塊名"

加載給定的模塊名modname,require函數首先會在表package.loaded中查看是否已經加載過,如果已經加載過,則會返回儲存在package.loaded[modname]中的模塊,否則,require函數將會嘗試為此模塊尋找一個加載器。

require函數將會被package.loader的數組引導來尋找適用于該模塊的加載器,(package.loaders,是一個被require函數用來控制如何加載模塊的表或者說數組)我們可以自己改變require函數尋找模塊的方法,下面是package.loaders的默認配置的下的解釋:

首先,require函數會查看package.preload[modname](用來儲存特定模塊加載器的表),如果有值(該值應是一個函數),則改值就是要找的加載器。否則,require函數將會通過儲存在package.path中的路徑來尋找一個Lua 加載器。如果也失敗了,requier函數則會通過儲存在package.cpath中的路徑來尋找一個C 加載器。如果也失敗了,require函數將會嘗試使用一個package.loaders中的通用的加載器——all-in-one 加載器。

一旦找到加載器,require函數會傳遞一個單一的參數模塊名modname到這個加載器,如果加載器有任何的返回值,require函數會將返回的值連同模塊名modname會注冊到表 package.loaded[modname]中。如果加載器沒有返回值并且還沒有任何值連同模塊名modname會注冊到表 package.loaded[modname]中,那么require函數將會注冊 true 到該鍵值對的入口。任何情況下,require 函數都會返回表 package.loaded[modname]最終的值。

如果在加載或者運行該模塊,亦或者完全沒有找到該模塊的加載器,則require函數會顯示error。

將上方simpleMod.lua放置在當前目錄的子目錄Util下,調用代碼:

--file: testMod.luaprint("Before the require function , packages in the package.loaded :") for k in pairs(package.loaded) do print(k) endprint("package.preload loader number : "..#package.preload)--lua5.1中的package.loaders 在lua5.2之后版本中更名為package.searchers --所以使用package.loaders or package.searchers來兼容版本 for k,v in pairs(package.loaders or package.searchers) do print("loader : "..k .. " "..tostring(v)) end--require function ,PS: The Util Is A Subdirectory of current directory local Mod = require "Util.simpleMod"print("\nAfter the require function , the table package.loaded") for k in pairs(package.loaded) do print(k) end--simpleMod's usage code local mod = Mod:New("TestFeature") mod:Update()print("\nModFeature Name : "..mod.Name .. "\nVersion : "..mod._VERSION)

輸出結果:

?

回到頂部

module函數

簡化module的創建

  • require會將模塊名modname傳遞給loader,在loader加載模塊時,我們可以在模塊中接收傳遞的模塊名

  • 有時我們會漏寫創建模塊最后的return語句,我們可以將所有與模塊創建相關的設置任務都集中在開頭,
    消除return語句的一種方法是,loader加載模塊時將模塊名modname以及模塊注冊至表package.loaded[modname]中

代碼如下:

--file: simpleMod.lualocal _Mod = {} _Mod._Mod = _Modlocal modname = ... _G[modname] = _mod package.loaded[modname] = _Modfunction _Mod:New(name)local mod = {}mod.Name = name or "Default Name"mod._VERSION = 0.01return setmetatable(mod , {__index = self}) endfunction _Mod:Update()self._VERSION = self._VERSION + 0.01return self._VERSION end

Lua5.1 & setfenv (f, table)

Sets the environment to be used by the given function. f can be a Lua function or a number that specifies the function at that stack level: Level 1 is the function calling setfenv. setfenv returns the given function.

As a special case, when f is 0 setfenv changes the environment of the running thread. In this case, setfenv returns no values.

當我們在創建模塊或者訪問同一個模塊中的其它函數時,需要限定名稱,就比如上面代碼中的_Mod,為此,我們可以讓模塊的主程序塊有一個獨立的環境,這樣不僅它的所有函數都可共享這個table,而且它的所有全局變量也都記錄在這個table中。而模塊所要做的就是將這個table賦予模塊名和package.loaded。

這樣,我們在調用同一個模塊中的函數new時,也不用指定m了。在寫自己的模塊時,就省去了前綴;但是與此同時,當我們調用setfenv(1,m)函數之后,會將一個空table m作為環境,但是這樣之后就無法訪問前一個環境中全局變量了(例如setmetatablet之類的全局變量)

解決方法:
方法一:在調用setfenv(1,m)之前,為m設置元表,使元表的__index域指向_G,代碼如下:

--file: simpleMod.lualocal _Mod = {} _Mod._Mod = _Modlocal modname = ... _G[modname] = _mod package.loaded[modname] = _Mod--Before calling the func setfenv() ,set the mestatable {__index = _G} to the _mod setmetatable(_Mod,{__index = _G}) setfenv(1,_Mod)function New(self,name)local mod = {}mod.Name = name or "Default Name"mod._VERSION = 0.01return setmetatable(mod , {__index = self}) endfunction Update(self)self._VERSION = self._VERSION + 0.01return self._VERSION end

方法二:在調用setfenv(1,m)之前,使用局部變量將全局變量_G保存起來,代碼如下:

--file: simpleMod.lualocal _Mod = {} _Mod._Mod = _Modlocal modname = ... _G[modname] = _mod package.loaded[modname] = _Mod--Before calling the func setfenv() ,storage _G to the local variable local _G = _G setfenv(1,_Mod)function New(self,name)local mod = {}mod.Name = name or "Default Name"mod._VERSION = 0.01--This way to use the variables in the _G tablereturn _G.setmetatable(mod , {__index = self}) endfunction Update(self)self._VERSION = self._VERSION + 0.01return self._VERSION end

方法三:在調用setfenv(1,m)之前,只將需要使用的全局變量保存起來,代碼如下:

--file: simpleMod.lualocal _Mod = {} _Mod._Mod = _Modlocal modname = ... _G[modname] = _mod package.loaded[modname] = _Mod--Before calling the func setfenv() ,storage useful variable the local variable local setmetatable = setmetatable setfenv(1,_Mod)function New(self,name)local mod = {}mod.Name = name or "Default Name"mod._VERSION = 0.01--This way to use the variables in the _G tablereturn setmetatable(mod , {__index = self}) endfunction Update(self)self._VERSION = self._VERSION + 0.01return self._VERSION end

Lua5.1 & module(...)

在Lua 5.1中,可以用module(...)的函數來代替以下代碼:

-- local _Mod = {} -- _Mod._Mod = _Mod-- local modname = ... -- _G[modname] = _mod -- package.loaded[modname] = _Mod-- setfenv(1,_Mod)

由于在默認情況下,module不提供外部訪問,必須在調用它之前,為需要訪問的外部函數或模塊聲明適當的局部變量。然后Lua提供了一種更為方便的實現方式,即在調用module函數時,多傳入一個package.seeall的參數,相當于 setmetatable(_Mod, {__index = _G}):

module(...,package.seeall)

完整代碼:

--file: simpleMod.lua-- local _Mod = {} -- _Mod._Mod = _Mod-- local modname = ... -- _G[modname] = _mod -- package.loaded[modname] = _Mod--Before calling the func setfenv() ,set the mestatable {__index = _G} to the _mod -- setmetatable(_Mod,{__index = _G}) -- setfenv(1,_Mod)module(...,package.seeall)function New(self,name)local mod = {}mod.Name = name or "Default Name"mod._VERSION = 0.01--This way to use the variables in the _G tablereturn setmetatable(mod , {__index = self})endfunction Update(self)self._VERSION = self._VERSION + 0.01return self._VERSION end

Lua5.2之后

  • Function module is deprecated. It is easy to set up a module with regular Lua code. Modules are not expected to set global variables.

  • Functions setfenv and getfenv were removed, because of the changes in environments.

  • module函數被拋棄。用普通的Lua代碼就可以很容易的創建模塊。而模塊也不需要去設置全局變量。

  • setfenv以及getfenv函數被移除,因為會對環境產生改變。

Lua5.2之后,如果require引入使用module聲明和定義的模塊就會報錯

REF

http://lua-users.org/wiki/

http://www.lua.org/manual/5.1/manual.html#5.3

http://www.lua.org/manual/5.2/manual.html#pdf-package.searchers

https://www.runoob.com/manual/lua53doc/manual.html#pdf-require

http://www.jb51.net/article/55818.htm

https://moonbingbing.gitbooks.io/openresty-best-practices/lua/not_use_module.html

https://www.cnblogs.com/zsb517/p/6822870.html

?

?

總結

以上是生活随笔為你收集整理的require函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美日韩午夜 | 午夜小视频在线播放 | 可以看的毛片 | 国产福利精品在线 | 男女黄色录像 | 手机av在线 | 久久久久久久久久久久久女国产乱 | 欧美一区二区三区粗大 | 91精品国产91久久久久福利 | 欧美成人一二区 | 婷婷综合社区 | 一级特黄性色生活片 | 成人颜色网站 | 99久 | 日韩电影中文字幕 | 免费观看理伦片在线播放视频软件 | 国产午夜精品久久久久久久久久 | 毛片久久久久久 | 日本在线成人 | 日韩视频免费在线播放 | 欧美激情图 | 老司机免费在线视频 | 欧美不卡一区二区 | 国产一区二区免费在线观看 | 国产一级片黄色 | 色综合天天色综合 | 日韩一区二区三区在线观看视频 | 国产亚洲视频一区 | 久久丫精品忘忧草西安产品 | 99在线精品观看 | 日韩一级影视 | 波多野结衣一本 | av香港经典三级级 在线 | 精品人妻大屁股白浆无码 | 五月天婷婷色综合 | 日本一级做a爱片 | 欧美日韩国产成人在线 | 日本中文字幕在线看 | 国产玖玖 | 国产尤物视频在线观看 | 污片免费在线观看 | 久久蜜桃av | wwwav网站 | 久久丁香网 | 国产美女主播在线 | 久久精品99久久久久久久久 | 欧美三级黄色 | 五月婷婷综合色 | 久久久久久毛片 | 欧美深夜在线 | 成人日批视频 | 久久精品午夜福利 | 欧美一区二区三区色 | 久青草视频 | 美女精品视频 | 一直草| 久久综合亚洲 | 国产精品不卡一区二区三区 | 亚洲91精品 | 久久精品屋 | 夜夜草导航 | jizz视频| 无码专区久久综合久中文字幕 | 欧美色图首页 | 美日韩丰满少妇在线观看 | 日韩av电影网 | 国产亚洲女人久久久久毛片 | 久操福利视频 | 红桃视频一区二区三区免费 | 手机在线中文字幕 | 亚洲图片欧美另类 | 国内自拍真实伦在线观看 | 一区久久 | 朋友的姐姐2在线观看 | 中文字幕在线视频第一页 | 69av视频| 日韩av网站在线播放 | 亚洲午夜久久久久久久久久久 | 天堂av中文在线观看 | 亚洲欧美日韩电影 | 天堂在线精品视频 | 国产又色又爽又高潮免费 | 色吊丝一区二区 | 好吊色视频在线观看 | 色噜噜色综合 | 亚洲精品在线播放视频 | 欧美午夜寂寞影院 | 免费av网站在线播放 | 91视频福利 | 午夜a视频 | 久久久久久久中文字幕 | 国产一区二区三区中文字幕 | 亚洲码国产精品高潮在线 | ass精品国模裸体pics | 91久久久久久久 | 午夜老司机免费视频 | 性一交一黄一片 | 中文在线最新版天堂 | 国产香蕉9|