load (chunk [, chunkname [, mode [, env]]])
加載一個代碼塊。
如果 chunk
是一個字符串,代碼塊指這個字符串。 如果 chunk
是一個函數, load
不斷地調用它獲取代碼塊的片斷。 每次對 chunk
的調用都必須返回一個字符串緊緊連接在上次調用的返回串之后。 當返回空串、nil、或是不返回值時,都表示代碼塊結束。
如果沒有語法錯誤, 則以函數形式返回編譯好的代碼塊; 否則,返回 nil 加上錯誤消息。
如果結果函數有上值, env
被設為第一個上值。 若不提供此參數,將全局環境替代它。 所有其它上值初始化為 nil。 (當你加載主代碼塊時候,結果函數一定有且僅有一個上值 _ENV
(參見 §2.2))。 然而,如果你加載一個用函數(參見string.dump
, 結果函數可以有任意數量的上值) 創建出來的二進制代碼塊時,所有的上值都是新創建出來的。 也就是說它們不會和別的任何函數共享。
chunkname
在錯誤消息和調試消息中(參見 §4.9),用於代碼塊的名字。 如果不提供此參數,它默認為字符串chunk
。 chunk
不是字符串時,則為 "=(load)
" 。
字符串 mode
用於控制代碼塊是文本還是二進制(即預編譯代碼塊)。 它可以是字符串 "b
" (只能是二進制代碼塊), "t
" (只能是文本代碼塊), 或 "bt
" (可以是二進制也可以是文本)。 默認值為 "bt
"。
Lua 不會對二進制代碼塊做健壯性檢查。 惡意構造一個二進制塊有可能把解釋器弄崩潰。
skynet cluster里的應用
1 local function loadconfig(tmp) 2 if tmp == nil then 3 tmp = {} 4 if config_name then 5 local f = assert(io.open(config_name)) 6 local source = f:read "*a" 7 f:close() 8 assert(load(source, "@"..config_name, "t", tmp))() 9 end 10 end 11 for name,address in pairs(tmp) do 12 assert(type(address) == "string") 13 if node_address[name] ~= address then 14 -- address changed 15 if rawget(node_channel, name) then 16 node_channel[name] = nil -- reset connection 17 end 18 node_address[name] = address 19 end 20 end 21 end
http://blog.csdn.net/snlscript/article/details/17168861
前面一篇博文提到了,用load函數實現Lua的反射機制,但是沒有深入的講解load的用法。load的本質就是在Lua代碼中運行一段存儲在字符串中的代碼。但很快你會發現,它並不是將字符串去掉“引號”那么簡單,如:
- b = 200
- print(load("b"))
解析器毫不猶豫的給你一個error。因為load有另一層含義,它是將字符串的內容作為一個函數體返回。所以以下代碼才是正確的使用方法:
- b = 200
- print(load("return b")())
將上面的代碼其實等同於:
- b = 200
- function func()
- return b
- end
- print(func())
- load("return b") 就等於函數:
- function func()
- return b
- end
經過上面的試驗,我們知道了load封裝了一個以字符串內容為函數體的函數,所以我們用同樣的方法在load中傳入一個函數名:
- function add(a, b)
- return a + b
- end
- value = load("return add")()
- print(value(1, 2))
- --就等於:
- function func()
- return add
- end
- value = func()
- print(value(1, 2))