table等類型轉換成string,轉換結果可以直接當作lua代碼,傳進loadstring執行。
先上代碼再解釋:
local function fret(...) local args = {...} return function() return unpack(args) end end function stringify(val) return (({ ["nil"] = fret "nil", ["boolean"] = fret(tostring(val)), ["number"] = fret(val), ["function"]= function() return "function(...)".. "return loadstring(".. stringify(string.dump(val)).. ")(...)".. "end" end, ["string"] = function() local s = "\"" for c in val:gfind"." do s = s.."\\"..c:byte() end return s.."\"" end, ["table"] = function() local members = {} for k,v in pairs(val) do table.insert(members, "["..stringify(k).."]="..stringify(v)) end return "{"..table.concat(members,",").."}" end, })[type(val)] or function() error("cannot stringify type:"..type(val),2) end)() end
測試如下:
print(stringify"\"")--" local s = stringify{ b = false, n = 112.222, s = "aaaasddd", f = function() print "hello" end, f2= function(s) return s.."!!!" end, t = { name = "leo", age = 18 } } local t = loadstring("return "..s)() print(t.t.name)--leo print(t.f2"leo123")--leo123!!!
說明,fret不是必要的,是我寫的一個庫里的函數,作用是調用時返回參數。不想用它的話,可以用function() return ... end替換掉。
接口函數是stringify,可以把幾乎所有的常用數據轉換成字符串。
需要說明一下:
可以轉換function,但是function不能有upvalue,否則會失敗
傳入的string數據沒有任何限制,可以放心的使用轉義符、特殊字符、多字節字符等