首先須要明白,通常狀況下,咱們的定義的lua模塊的文件與模塊名(其實就是table的名字)是一致的,固然,不一致代碼也是能夠編譯的(親測),之因此這樣,本人認爲是爲了實際項目中管理的方便。如下是定義模塊的集中方式(文件名字是 GameMudle.lua):函數
方式一:this
1 GameModule = {}; 2 3 function GameModule.ShowName() 4 print("fun : ShowName"); 5 end 6 7 function GameModule.ShowInfo() 8 print("fun : ShowInfo"); 9 end 10 11 return GameModule;
假若有一天,咱們想要修改模塊的名字了,就須要逐行代碼的去修改對應的模塊名字,顯然,這實際很是不合理的。lua
如下是調整過的一種定義方式:spa
1 GameModule = {}; 2 3 local this = GameModule; 4 5 function this..ShowName() 6 print("fun : ShowName"); 7 end 8 9 function this.ShowInfo() 10 print("fun : ShowInfo"); 11 end 12 13 return this;
這樣的話,每次修改模塊的名字,咱們只須要去修改第一行和第三行就能夠了。可是還有一個問題,就是開始提到的,爲了工程管理的方便,模塊所在的lua文件名字與模塊名須要保持一致,這樣的話,咱們沒次更改模塊名字,code
須要同時修改模塊名和模塊所在的lua文件名,思考一下還有更好的定義模塊的方式嗎?顯然是有的(哈哈哈。。。)。blog
如下是另一種定義模塊的方式:io
1 local this = {}; 2 3 local moduleName = ...; --傳遞模塊名,能夠理解爲文件名 4 _G[moduleName] = this; --將全局環境設置爲 this 5 6 function this.ShowName() 7 print("fun : ShowName"); 8 end 9 10 function this.ShowInfo() 11 print("fun : ShowInfo"); 12 end 13 14 return this;
進一步簡化:編譯
1 local this = {}; 2 3 local moduleName = ...; --傳遞模塊名,能夠理解爲文件名 4 _G[moduleName] = this; --將全局環境設置爲 this,環境其實能夠理解爲一個表 5 setmetatable(this,{__index = _G}) --沒有這一句,全局的 print 等內置函數將不能使用 6 setfenv(1, this) --建立一個非全局環境 ,防止在全局環境中方法等命名的衝突,這裏改變的是運行環境 7 8 --全局環境設置爲 this ,因而,咱們直接定義函數的時候,不須要再帶 this 前綴。 9 --由於此時的全局環境就是M,不帶前綴去定義變量,就是全局變量,這時的全局變量是保存在 this 裏。 10 function ShowName() 11 print("fun : ShowName"); 12 end 13 14 function ShowInfo() 15 print("fun : ShowInfo"); 16 end
利用 module 函數進一步簡化模塊的定義:
1 module(..., package.seeall); 2 function ShowName() 3 print("fun : ShowName"); 4 end 5 6 function ShowInfo() 7 print("fun : ShowInfo"); 8 end
調用方式:table