我一直在尋找一些Lua的源代碼,我經常看到這樣的事情在文件的開頭:爲什麼要使全局Lua函數在本地?
local setmetatable, getmetatable, etc.. = setmetatable, getmetatable, etc..
難道他們只能讓當地的功能,讓Lua中訪問他們更快時經常使用?
我一直在尋找一些Lua的源代碼,我經常看到這樣的事情在文件的開頭:爲什麼要使全局Lua函數在本地?
local setmetatable, getmetatable, etc.. = setmetatable, getmetatable, etc..
難道他們只能讓當地的功能,讓Lua中訪問他們更快時經常使用?
本地數據位於堆棧上,因此它們可以更快地訪問它們。但是,我嚴重懷疑函數調用時間到setmetatable
實際上是一些程序的重要問題。
下面是這種情況的可能的解釋:
預防污染地球環境。模塊的現代Lua約定是不讓它們直接註冊到全局表中。他們應該建立一個本地函數表並返回它們。因此,只有的方式來訪問它們是一個局部變量。這迫使一些事情:
一個模塊不能意外覆蓋另一個模塊的功能。
如果模塊不小心做到這一點,模塊返回的表格中的原始函數仍然可以訪問。只有通過使用local modname = require "modname"
,您才能保證準確獲取該模塊所暴露的內容。
包含其他模塊的模塊不能相互干擾。您從require
獲得的表格始終是模塊存儲的內容。
有人過早優化誰讀「local
變量訪問更快」,然後決定讓一切local
。
一般來說,這是很好的做法。那麼,除非是因爲#2。
3.沉默一個認爲調用內置插件這樣的linter因爲rawset或ipairs是不好的。 – andyn 2015-06-25 10:26:36
我這樣做,因爲它讓我看到我的每一個模塊
此外,它可以保護你免受他人更改功能在全球環境中使用的功能。 這是一個免費(過早)優化是一個獎金。
沒有什麼可以阻止您的模塊使用不在該列表中的函數。所以如果你突然需要一個全局函數而忘記將它添加到列表中,那麼你正在使用全局變量。另外,如果有人改變全局函數,那麼他們可能會有這樣做的理由,比如監視某些函數的使用等等。 – 2012-02-09 14:16:49
其實有;我有一個預先提交的鉤子,它使用luac來搜索GETGLOBAL操作碼併發出警告。 – daurnimator 2012-02-09 18:26:33
這是很多工作來實現這麼簡單的事情。您剛剛使用環境爲每個功能提供了特定的全局空間,因此它們不會影響其他人的環境。在Lua書中的編程告訴你所有關於如何做到這一點。 – 2012-02-09 18:40:58
除了尼科爾流星錘的答案,我會添加到第3點:
如果函數已經從沙箱中排除,並且代碼是從沙箱中加載的,那麼它將不起作用。但是,如果代碼先加載,那麼沙箱可以調用加載的代碼,並能夠從沙箱中排除setmetatable等。
另一個微妙的好處是:它清楚地記錄了模塊導入哪些變量(函數,模塊)。如果您使用模塊語句,則會強制執行此類聲明,因爲全局環境會被替換(因此全局變量不可用)。
你可能想看看http://stackoverflow.com/questions/4643814/why-would-this-lua-optimization-hack-help – 2012-02-08 22:29:38