0.前言
我的理解中dump函数其实和print函数是没有什么区别的,无非就是多了一个打印table的功能,一般来说当作工具使用就好了,也不会去解析它的函数,但当你需要打印table到文件中的时候,你就需要学习一下了,毕竟cocos写得代码肯定比网上copy来的靠谱嘛!
1.函数调用及输出
local list = {
ver = 0.03,
stage = {
{name="update.png", fileCheck=false, code="13bd035daeb460518cc055670883e9ff", act="res"},
{name="bg.png", fileCheck=false, code="13bd035daeb460518cc055670883e9ff", act="res"},
{name="ui_loading_bar.png", fileCheck=false, code="13bd035daeb460518cc055670883e9ff", act="res"},
{name="ui_loading_bg.png", fileCheck=false, code="13bd035daeb460518cc055670883e9ff", act="res"},
}
}
dump(list)
2.函数解析
之前都是看别人的教程,很少自己写博客,常常对博主的文笔嗤之以鼻,但当自己写得时候,才明白了博主的难处。首先,博文大多是博主的归纳,并非是教程,所以看起来晦涩难懂;其次将脑中所想化为笔下所写,还是挺有难度的。因此我觉得最好理解本文最好的方式还是自己打开源码看,看到不懂之处再回头来看本文的注释,写得不好,望请见谅!
--[[
--value:你要打印的信息
--desciption:打印信息前的描述
--nesting:最大的打印层级
--]]
function dump(value, desciption, nesting)
--默认打印层级为3
if type(nesting) ~= "number" then nesting = 3 end
local lookupTable = {}
local result = {}
--[[
--若参数为字符串,则将其转换为双引号包裹的字符串
--否则转换为普通字符串
--]]
local function _v(v)
if type(v) == "string" then
v = "\"" .. v .. "\""
end
return tostring(v)
end
--[[
--打印调用堆栈
--]]
local traceback = string.split(debug.traceback("", 2), "\n")
print("dump from: " .. string.trim(traceback[3]))
--[[
--value:要打印的值
--desciption:描述,ex."stage","1","act"
--indent:desciption前的空白距离
--nest:嵌套层级
--keylen:value下key的最大长度,若value为stage下的table1,则keylen则为fileCheck的长度
--]]
local function _dump(value, desciption, indent, nest, keylen)
desciption = desciption or "<var>"
--spc为空格字符串,用于字符串对齐
local spc = ""
if type(keylen) == "number" then
--将空格拷贝n份并连接
spc = string.rep(" ", keylen - string.len(_v(desciption)))
end
if type(value) ~= "table" then --value为键值对
result[#result +1 ] = string.format("%s%s%s = %s", indent, _v(desciption), spc, _v(value))
elseif lookupTable[value] then --此处用于避免value中含有递归嵌套而导致的死循环
result[#result +1 ] = string.format("%s%s%s = *REF*", indent, desciption, spc)
else
lookupTable[value] = true
if nest > nesting then --当前层级超过最大层级,则输出下列内容
result[#result +1 ] = string.format("%s%s = *MAX NESTING*", indent, desciption)
else
result[#result +1 ] = string.format("%s%s = {", indent, _v(desciption))
local indent2 = indent.." "
local keys = {}
local keylen = 0
local values = {}
for k, v in pairs(value) do
keys[#keys + 1] = k
local vk = _v(k)
local vkl = string.len(vk)
if vkl > keylen then keylen = vkl end
values[k] = v
end
--对value下的key进行排序
table.sort(keys, function(a, b)
if type(a) == "number" and type(b) == "number" then
return a < b
else
return tostring(a) < tostring(b)
end
end)
--因为value为table,所以在此处递归遍历
for i, k in ipairs(keys) do
_dump(values[k], k, indent2, nest + 1, keylen)
end
result[#result +1] = string.format("%s}", indent)
end
end
end
_dump(value, desciption, "- ", 1)
--打印生成的转换后的数据
for i, line in ipairs(result) do
print(line)
end
end
3.结语
写本文的目的不是为了解析dump函数而学习,而是为了实现将table打印至文件的功能,希望读者理解后也能顺带实现一下此功能,然后通过dofile导入文件,验证你导出的table是否正确。
--打印table至文件
function printTb2File(value, tableName, filepath)
tableName = tableName or "table"
filepath = filepath or device.writablePath .. tableName
local desciption = "local " .. tableName
local nesting = 100
local lookupTable = {}
local result = {}
local function _v(v)
if type(v) == "string" then
v = "\"" .. v .. "\""
end
return tostring(v)
end
local function _dump(value, desciption, indent, nest, keylen)
desciption = desciption or "local list"
local spc = ""
if type(keylen) == "number" then
spc = string.rep(" ", keylen - string.len(desciption))
end
if type(value) ~= "table" then
result[#result +1 ] = string.format("%s%s%s = %s,", indent, desciption, spc, _v(value))
elseif lookupTable[value] then
result[#result +1 ] = string.format("%s%s%s = *REF*", indent, desciption, spc)
else
lookupTable[value] = true
if nest > nesting then
result[#result +1 ] = string.format("%s%s = *MAX NESTING*", indent, desciption)
else
if desciption == "" then
result[#result +1 ] = string.format("%s{", indent)
else
result[#result +1 ] = string.format("%s%s = {", indent, desciption)
end
local indent2 = indent.." "
local keys = {}
local keylen = 0
local values = {}
for k, v in pairs(value) do
keys[#keys + 1] = k
local vk = _v(k)
local vkl = string.len(vk)
if vkl > keylen then keylen = vkl end
values[k] = v
end
for i, k in ipairs(keys) do
local result = tonumber(k)
if result == nil then
_dump(values[k], k, indent2, nest + 1, keylen)
else
_dump(values[k], "", indent2, nest + 1, keylen)
end
end
result[#result +1] = string.format("%s},", indent)
end
end
end
_dump(value, desciption, "", 1)
result[#result] = "}"
io.writefile(filepath, "", "wb+")
for i, line in ipairs(result) do
io.writefile(filepath, line .. "\n", "a+")
end
io.writefile(filepath, "return " .. tableName, "a+")
end
网友评论