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数据没有任何限制,可以放心的使用转义符、特殊字符、多字节字符等