前言
一直用lua 作为游戏脚本语言来编程,而table在lua的数据结构中占据了大半壁江山,所以几乎每天的编程都离不开对table的使用,lua的table确实好用,插入、删除、查询都非常的方便,但是用多了也就渐渐的发现了一些问题,比如不知道table中都有哪些值,调试的时候面对巨大的table不知从何下手等等,所以我就有了一个想法,想看看lua中能不能直接打印table的值,网上看了一些文章发现都不太适合,决定自己动手写一个,要打印table这样的结构当然得用递归思想了,话不多说,直接上代码和大家分享一下。
代码示例
function dumptree(obj, width)
-- 递归打印函数
local dump_obj;
local end_flag = {};
local function make_indent(layer, is_end)
local subIndent = string.rep(" ", width)
local indent = "";
end_flag[layer] = is_end;
local subIndent = string.rep(" ", width)
for index = 1, layer - 1 do
if end_flag[index] then
indent = indent.." "..subIndent
else
indent = indent.."|"..subIndent
end
end
if is_end then
return indent.."└"..string.rep("─", width).." "
else
return indent.."├"..string.rep("─", width).." "
end
end
local function make_quote(str)
str = string.gsub(str, "[%c\\\"]", {
["\t"] = "\\t",
["\r"] = "\\r",
["\n"] = "\\n",
["\""] = "\\\"",
["\\"] = "\\\\",
})
return "\""..str.."\""
end
local function dump_key(key)
if type(key) == "number" then
return key .. "] "
elseif type(key) == "string" then
return tostring(key).. ": "
end
end
local function dump_val(val, layer)
if type(val) == "table" then
return dump_obj(val, layer)
elseif type(val) == "string" then
return make_quote(val)
else
return tostring(val)
end
end
local function count_elements(obj)
local count = 0
for k, v in pairs(obj) do
count = count + 1
end
return count
end
dump_obj = function(obj, layer)
if type(obj) ~= "table" then
return count_elements(obj)
end
layer = layer + 1
local tokens = {}
local max_count = count_elements(obj)
local cur_count = 1
for k, v in pairs(obj) do
local key_name = dump_key(k)
if type(v) == "table" then
key_name = key_name.."\n"
end
table.insert(tokens, make_indent(layer, cur_count == max_count)
.. key_name .. dump_val(v, layer))
cur_count = cur_count + 1
end
-- 处理空table
if max_count == 0 then
table.insert(tokens, make_indent(layer, true) .. "{ }")
end
return table.concat(tokens, "\n")
end
if type(obj) ~= "table" then
return "the params you input is "..type(obj)..
", not a table, the value is --> "..tostring(obj)
end
width = width or 2
return "root-->"..tostring(obj).."\n"..dump_obj(obj, 0)
end
运行示例
local t = {
a = 1,
b = 2,
[1] = 34,
["1"] =56,
pos = {
x = 100,
y = 200,
z = 400,
target = {
pos = {
x = 666,
y = 456,
},
src = "name",
dest = nil,
from = "china \n beijing"
}
},
[88] = 88888,
[9.7] = 22222,
func = function()
print("this is a function")
end,
["key"] = "value",
[98] = {
name = "albert",
age = "18",
},
["98"] = {},
}
-- 调用函数运行
print(dumptree(t))
运行结果
root-->table: 0031D748
├── a: 1
├── b: 2
├── 9.7] 22222
├── 1] 34
├── 98]
| ├── name: "albert"
| └── age: "18"
├── key: "value"
├── func: function: 00318140
├── 88] 88888
├── 98:
| └── { }
├── 1: 56
└── pos:
├── y: 200
├── x: 100
├── target:
| ├── src: "name"
| ├── from: "china \n beijing"
| └── pos:
| ├── y: 456
| └── x: 666
└── z: 400
总结
- 这个函数是以树形的结构打印table,看起来比原型打印更加清晰。
- 结果中将一个空的table表示为
{}
的形式。 - 参数
width
主要是控制树杈的宽度,默认为2,会出现图中所表现的结果。 - 如果在使用过程中有什么问题,欢迎大家及时指出来,我会及时改正。