关于 lua:如何将表转储到控制台?


How to dump a table to console?

我无法显示包含嵌套表(n-deep)的表的内容。我想通过 print 语句或快速而肮脏的东西将它转储到标准输出或控制台,但我不知道如何。我正在寻找使用 gdb 打印 NSDictionary 时得到的粗略等价物。


我发现这个很有用。因为如果递归它也可以打印嵌套表。它没有在输出中给出最漂亮的格式,但是对于这样一个简单的功能,它很难在调试时被击败。

1
2
3
4
5
6
7
8
9
10
11
12
function dump(o)
   if type(o) == 'table' then
      local s = '{ '
      for k,v in pairs(o) do
         if type(k) ~= 'number' then k = '"'..k..'"' end
         s = s .. '['..k..'] = ' .. dump(v) .. ','
      end
      return s .. '} '
   else
      return tostring(o)
   end
end

例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
local people = {
   {
      name ="Fred",
      address ="16 Long Street",
      phone ="123456"
   },

   {
      name ="Wilma",
      address ="16 Long Street",
      phone ="123456"
   },

   {
      name ="Barney",
      address ="17 Long Street",
      phone ="123457"
   }

}

print("People:", dump(people))

产生以下输出:

People: { [1] = { ["address"] = 16 Long Street,["phone"] =
123456,["name"] = Fred,} ,[2] = { ["address"] = 16 Long
Street,["phone"] = 123456,["name"] = Wilma,} ,[3] = { ["address"] = 17
Long Street,["phone"] = 123457,["name"] = Barney,} ,}


我知道这个问题已经被标记为已回答,但让我在这里插入我自己的库。它叫做inspect.lua,你可以在这里找到它:

https://github.com/kikito/inspect.lua

它只是一个您可以从任何其他文件中获取的文件。它返回一个将任何 Lua 值转换为人类可读字符串的函数:

1
2
3
4
5
6
7
8
local inspect = require('inspect')

print(inspect({1,2,3})) -- {1, 2, 3}
print(inspect({a=1,b=2})
-- {
--   a = 1
--   b = 2
-- }

它正确缩进子表,并正确处理"递归表"(包含对自身的引用的表),因此它不会陷入无限循环。它以合理的方式对值进行排序。它还打印元表信息。

问候!


请随意浏览关于表序列化的 Lua Wiki。它列出了如何将表转储到控制台的几种方法。

您只需要选择最适合您的。有很多方法可以做到这一点,但我通常最终使用 Penlight 中的一种:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> t = { a = { b = { c ="Hello world!", 1 }, 2, d = { 3 } } }
> require 'pl.pretty'.dump(t)
{
  a = {
    d = {
      3
    },
    b = {
      c ="Hello world!",
      1
    },
    2
  }
}


找到了这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- Print contents of `tbl`, with indentation.
-- `indent` sets the initial level of indentation.
function tprint (tbl, indent)
  if not indent then indent = 0 end
  for k, v in pairs(tbl) do
    formatting = string.rep(" ", indent) .. k ..":"
    if type(v) =="table" then
      print(formatting)
      tprint(v, indent+1)
    elseif type(v) == 'boolean' then
      print(formatting .. tostring(v))      
    else
      print(formatting .. v)
    end
  end
end

从这里
https://gist.github.com/ripter/4270799

对我来说很好用……


我见过的大多数纯 lua 打印表函数都存在深度递归问题
并且在太深时往往会导致堆栈溢出。这个印刷品
我写的表函数没有这个问题。由于它处理连接的方式,它还应该能够处理非常大的表。在我个人对这个函数的使用中,它在大约一秒钟内输出了 63k 行到文件。

输出还保留了lua语法,脚本可以很容易地修改
如果修改为允许,则通过将输出写入文件来进行简单的持久存储
仅要格式化的数字、布尔值、字符串和表格数据类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
function print_table(node)
    local cache, stack, output = {},{},{}
    local depth = 1
    local output_str ="{\
"


    while true do
        local size = 0
        for k,v in pairs(node) do
            size = size + 1
        end

        local cur_index = 1
        for k,v in pairs(node) do
            if (cache[node] == nil) or (cur_index >= cache[node]) then

                if (string.find(output_str,"}",output_str:len())) then
                    output_str = output_str ..",\
"

                elseif not (string.find(output_str,"\
"
,output_str:len())) then
                    output_str = output_str .."\
"

                end

                -- This is necessary for working with HUGE tables otherwise we run out of memory using concat on huge strings
                table.insert(output,output_str)
                output_str =""

                local key
                if (type(k) =="number" or type(k) =="boolean") then
                    key ="["..tostring(k).."]"
                else
                    key ="['"..tostring(k).."']"
                end

                if (type(v) =="number" or type(v) =="boolean") then
                    output_str = output_str .. string.rep('\\t',depth) .. key .." ="..tostring(v)
                elseif (type(v) =="table") then
                    output_str = output_str .. string.rep('\\t',depth) .. key .." = {\
"

                    table.insert(stack,node)
                    table.insert(stack,v)
                    cache[node] = cur_index+1
                    break
                else
                    output_str = output_str .. string.rep('\\t',depth) .. key .." = '"..tostring(v).."'"
                end

                if (cur_index == size) then
                    output_str = output_str .."\
"
.. string.rep('\\t',depth-1) .."}"
                else
                    output_str = output_str ..","
                end
            else
                -- close the table
                if (cur_index == size) then
                    output_str = output_str .."\
"
.. string.rep('\\t',depth-1) .."}"
                end
            end

            cur_index = cur_index + 1
        end

        if (size == 0) then
            output_str = output_str .."\
"
.. string.rep('\\t',depth-1) .."}"
        end

        if (#stack > 0) then
            node = stack[#stack]
            stack[#stack] = nil
            depth = cache[node] == nil and depth + 1 or depth - 1
        else
            break
        end
    end

    -- This is necessary for working with HUGE tables otherwise we run out of memory using concat on huge strings
    table.insert(output,output_str)
    output_str = table.concat(output)

    print(output_str)
end

这是一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
local t = {
    ["abe"] = {1,2,3,4,5},
   "string1",
    50,
    ["depth1"] = { ["depth2"] = { ["depth3"] = { ["depth4"] = { ["depth5"] = { ["depth6"] = { ["depth7"]= { ["depth8"] = { ["depth9"] = { ["depth10"] = {1000}, 900}, 800},700},600},500}, 400 }, 300}, 200}, 100},
    ["ted"] = {true,false,"some text"},
   "string2",
    [function() return end] = function() return end,
    75
}

print_table(t)

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{
    [1] = 'string1',
    [2] = 50,
    [3] = 'string2',
    [4] = 75,
    ['abe'] = {
        [1] = 1,
        [2] = 2,
        [3] = 3,
        [4] = 4,
        [5] = 5
    },
    ['function: 06472B70'] = 'function: 06472A98',
    ['depth1'] = {
        [1] = 100,
        ['depth2'] = {
            [1] = 200,
            ['depth3'] = {
                [1] = 300,
                ['depth4'] = {
                    [1] = 400,
                    ['depth5'] = {
                        [1] = 500,
                        ['depth6'] = {
                            [1] = 600,
                            ['depth7'] = {
                                [1] = 700,
                                ['depth8'] = {
                                    [1] = 800,
                                    ['depth9'] = {
                                        [1] = 900,
                                        ['depth10'] = {
                                            [1] = 1000
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    ['ted'] = {
        [1] = true,
        [2] = false,
        [3] = 'some text'
    }
}


如前所述,您必须编写它。
这是我的简陋版本:(超级基本的)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function tprint (t, s)
    for k, v in pairs(t) do
        local kfmt = '["' .. tostring(k) ..'"]'
        if type(k) ~= 'string' then
            kfmt = '[' .. k .. ']'
        end
        local vfmt = '"'.. tostring(v) ..'"'
        if type(v) == 'table' then
            tprint(v, (s or '')..kfmt)
        else
            if type(v) ~= 'string' then
                vfmt = tostring(v)
            end
            print(type(t)..(s or '')..kfmt..' = '..vfmt)
        end
    end
end

示例:

1
2
local mytbl = { ['1']="a", 2, 3, b="c", t={d=1} }
tprint(mytbl)

输出(Lua 5.0):

1
2
3
4
5
table[1] = 2
table[2] = 3
table["1"] ="a"
table["t"]["d"] = 1
table["b"] ="c"


最简单的方法,循环引用处理等等:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function dump(t, indent, done)
    done = done or {}
    indent = indent or 0

    done[t] = true

    for key, value in pairs(t) do
        print(string.rep("\\t", indent))

        if type(value) =="table" and not done[value] then
            done[value] = true
            print(key,":\
"
)

            dump(value, indent + 2, done)
            done[value] = nil
        else
            print(key,"\\t=\\t", value,"\
"
)
        end
    end
end


我使用自己的函数来打印表格的内容,但不确定它在您的环境中的转换效果如何:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
---A helper function to print a table's contents.
---@param tbl table @The table to print.
---@param depth number @The depth of sub-tables to traverse through and print.
---@param n number @Do NOT manually set this. This controls formatting through recursion.
function PrintTable(tbl, depth, n)
  n = n or 0;
  depth = depth or 5;

  if (depth == 0) then
      print(string.rep(' ', n).."...");
      return;
  end

  if (n == 0) then
      print("");
  end

  for key, value in pairs(tbl) do
      if (key and type(key) =="number" or type(key) =="string") then
          key = string.format("["%s"]", key);

          if (type(value) =="table") then
              if (next(value)) then
                  print(string.rep(' ', n)..key.." = {");
                  PrintTable(value, depth - 1, n + 4);
                  print(string.rep(' ', n).."},");
              else
                  print(string.rep(' ', n)..key.." = {},");
              end
          else
              if (type(value) =="string") then
                  value = string.format(""%s"", value);
              else
                  value = tostring(value);
              end

              print(string.rep(' ', n)..key.." ="..value..",");
          end
      end
  end

  if (n == 0) then
      print("");
  end
end

格式为JSON(以后可以在IDE中"美化"):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
local function format_any_value(obj, buffer)
    local _type = type(obj)
    if _type =="table" then
        buffer[#buffer + 1] = '{"'
        for key, value in next, obj, nil do
            buffer[#buffer + 1] = tostring(key) .. '":'
            format_any_value(value, buffer)
            buffer[#buffer + 1] = ',"'
        end
        buffer[#buffer] = '}' -- note the overwrite
    elseif _type =="string" then
        buffer[#buffer + 1] = '"' .. obj .. '"'
    elseif _type =="boolean" or _type =="number" then
        buffer[#buffer + 1] = tostring(obj)
    else
        buffer[#buffer + 1] = '"???' .. _type .. '???"'
    end
end

用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
local function format_as_json(obj)
    if obj == nil then return"null" else
        local buffer = {}
        format_any_value(obj, buffer)
        return table.concat(buffer)
    end
end

local function print_as_json(obj)
    print(_format_as_json(obj))
end

print_as_json {1, 2, 3}
print_as_json(nil)
print_as_json("string")
print_as_json {[1] = 1, [2] = 2, three = { { true } }, four ="four"}

顺便说一句,我还写了其他几个解决方案:一个非常快的解决方案,一个带有特殊字符转义的解决方案:https://github.com/vn971/fast_json_encode


恐怕您必须自己编写代码。这是我写的,可能对你有用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
function printtable(table, indent)

  indent = indent or 0;

  local keys = {};

  for k in pairs(table) do
    keys[#keys+1] = k;
    table.sort(keys, function(a, b)
      local ta, tb = type(a), type(b);
      if (ta ~= tb) then
        return ta < tb;
      else
        return a < b;
      end
    end);
  end

  print(string.rep('  ', indent)..'{');
  indent = indent + 1;
  for k, v in pairs(table) do

    local key = k;
    if (type(key) == 'string') then
      if not (string.match(key, '^[A-Za-z_][0-9A-Za-z_]*$')) then
        key ="['"..key.."']";
      end
    elseif (type(key) == 'number') then
      key ="["..key.."]";
    end

    if (type(v) == 'table') then
      if (next(v)) then
        printf("%s%s =", string.rep('  ', indent), tostring(key));
        printtable(v, indent);
      else
        printf("%s%s = {},", string.rep('  ', indent), tostring(key));
      end
    elseif (type(v) == 'string') then
      printf("%s%s = %s,", string.rep('  ', indent), tostring(key),"'"..v.."'");
    else
      printf("%s%s = %s,", string.rep('  ', indent), tostring(key), tostring(v));
    end
  end
  indent = indent - 1;
  print(string.rep('  ', indent)..'}');
end


metalua的table.tostring方法其实很完善。它处理嵌套表,缩进级别是可变的,...
见 https://github.com/fab13n/metalua/blob/master/src/lib/metalua/table2.lua


这是我的版本,支持排除表和用户数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
-- Lua Table View by Elertan
table.print = function(t, exclusions)
    local nests = 0
    if not exclusions then exclusions = {} end
    local recurse = function(t, recurse, exclusions)
        indent = function()
            for i = 1, nests do
                io.write("   ")
            end
        end
        local excluded = function(key)
            for k,v in pairs(exclusions) do
                if v == key then
                    return true
                end
            end
            return false
        end
        local isFirst = true
        for k,v in pairs(t) do
            if isFirst then
                indent()
                print("|")
                isFirst = false
            end
            if type(v) =="table" and not excluded(k) then
                indent()
                print("|->"..k..":"..type(v))
                nests = nests + 1
                recurse(v, recurse, exclusions)
            elseif excluded(k) then
                indent()
                print("|->"..k..":"..type(v))
            elseif type(v) =="userdata" or type(v) =="function" then
                indent()
                print("|->"..k..":"..type(v))
            elseif type(v) =="string" then
                indent()
                print("|->"..k..":".."""..v..""")
            else
                indent()
                print("|->"..k..":"..v)
            end
        end
        nests = nests - 1
    end

    nests = 0
    print("### START TABLE ###")
    for k,v in pairs(t) do
        print("root")
        if type(v) =="table" then
            print("|->"..k..":"..type(v))
            nests = nests + 1
            recurse(v, recurse, exclusions)
        elseif type(v) =="userdata" or type(v) =="function" then
            print("|->"..k..":"..type(v))
        elseif type(v) =="string" then
            print("|->"..k..":".."""..v..""")
        else
            print("|->"..k..":"..v)
        end
    end
    print("### END TABLE ###")
end

这是一个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
t = {
    location = {
       x = 10,
       y = 20
    },
    size = {
      width = 100000000,
      height = 1000,
    },
    name ="Sidney",
    test = {
        hi ="lol",
    },
    anotherone = {
        1,
        2,
        3
    }
}

table.print(t, {"test" })

打印:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
   ### START TABLE ###
root
|-> size: table
    |
    |-> height: 1000
    |-> width: 100000000
root
|-> location: table
    |
    |-> y: 20
    |-> x: 10
root
|-> anotherone: table
    |
    |-> 1: 1
    |-> 2: 2
    |-> 3: 3
root
|-> test: table
    |
    |-> hi:"lol"
root
|-> name:"Sidney"
### END TABLE ###

请注意,根目录不会删除排除项


添加另一个版本。这个也尝试迭代用户数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
function inspect(o,indent)
    if indent == nil then indent = 0 end
    local indent_str = string.rep("   ", indent)
    local output_it = function(str)
        print(indent_str..str)
    end

    local length = 0

    local fu = function(k, v)
        length = length + 1
        if type(v) =="userdata" or type(v) == 'table' then
            output_it(indent_str.."["..k.."]")
            inspect(v, indent+1)
        else
            output_it(indent_str.."["..k.."]"..tostring(v))
        end
    end

    local loop_pairs = function()
        for k,v in pairs(o) do fu(k,v) end
    end

    local loop_metatable_pairs = function()
        for k,v in pairs(getmetatable(o)) do fu(k,v) end
    end

    if not pcall(loop_pairs) and not pcall(loop_metatable_pairs) then
        output_it(indent_str.."[[??]]")
    else
        if length == 0 then
            output_it(indent_str.."{}")
        end
    end
end

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
--~ print a table
function printTable(list, i)

    local listString = ''
--~ begin of the list so write the {
    if not i then
        listString = listString .. '{'
    end

    i = i or 1
    local element = list[i]

--~ it may be the end of the list
    if not element then
        return listString .. '}'
    end
--~ if the element is a list too call it recursively
    if(type(element) == 'table') then
        listString = listString .. printTable(element)
    else
        listString = listString .. element
    end

    return listString .. ', ' .. printTable(list, i + 1)

end


local table = {1, 2, 3, 4, 5, {'a', 'b'}, {'G', 'F'}}
print(printTable(table))

嗨,伙计,我用纯 Lua 编写了一个简单的代码,它有一个错误(在列表的最后一个元素之后写一个逗号)但是我如何快速将它作为原型编写,我会让它适应你它满足您的需求。


转成json再打印。

1
2
3
    local json = require('cjson')
    json_string = json.encode(this_table)
    print (json_string)

在 lua 中转储表的简单示例

我建议使用 serpent.lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
local function parser(value, indent, subcategory)
  local indent = indent or 2
  local response = '(\
'

  local subcategory = type(subcategory) == 'number' and subcategory or indent
  for key, value in pairs(value) do
    if type(value) == 'table' then
      value = parser(value, indent, subcategory + indent)

    elseif type(value) == 'string' then
      value = '\''.. value .. '\''

    elseif type(value) ~= 'number' then
      value = tostring(value)
    end

    if type(tonumber(key)) == 'number' then
        key = '[' .. key .. ']'
   elseif not key:match('^([A-Za-z_][A-Za-z0-9_]*)$') then
      key = '[\'' .. key .. '\']'
    end
    response = response .. string.rep(' ', subcategory) .. key .. ' = ' .. value .. ',\
'

  end
  return response .. string.rep(' ', subcategory - indent) .. ')'

end

示例

1
2
response = parser{1,2,3, {ok = 10, {}}}
print(response)

结果

1
2
3
4
5
6
7
8
9
(
  [1] = 1,
  [2] = 2,
  [3] = 3,
  [4] = (
    [1] = (),
    ok = 10
  )
)

我已经谦虚地修改了一点 Alundaio 代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
-- by Alundaio
-- KK modified 11/28/2019

function dump_table_to_string(node, tree, indentation)
    local cache, stack, output = {},{},{}
    local depth = 1


    if type(node) ~="table" then
        return"only table type is supported, got" .. type(node)
    end

    if nil == indentation then indentation = 1 end

    local NEW_LINE ="\
"

    local TAB_CHAR =""

    if nil == tree then
        NEW_LINE ="\
"

    elseif not tree then
        NEW_LINE =""
        TAB_CHAR =""
    end

    local output_str ="{" .. NEW_LINE

    while true do
        local size = 0
        for k,v in pairs(node) do
            size = size + 1
        end

        local cur_index = 1
        for k,v in pairs(node) do
            if (cache[node] == nil) or (cur_index >= cache[node]) then

                if (string.find(output_str,"}",output_str:len())) then
                    output_str = output_str .."," .. NEW_LINE
                elseif not (string.find(output_str,NEW_LINE,output_str:len())) then
                    output_str = output_str .. NEW_LINE
                end

                -- This is necessary for working with HUGE tables otherwise we run out of memory using concat on huge strings
                table.insert(output,output_str)
                output_str =""

                local key
                if (type(k) =="number" or type(k) =="boolean") then
                    key ="["..tostring(k).."]"
                else
                    key ="['"..tostring(k).."']"
                end

                if (type(v) =="number" or type(v) =="boolean") then
                    output_str = output_str .. string.rep(TAB_CHAR,depth*indentation) .. key .." ="..tostring(v)
                elseif (type(v) =="table") then
                    output_str = output_str .. string.rep(TAB_CHAR,depth*indentation) .. key .." = {" .. NEW_LINE
                    table.insert(stack,node)
                    table.insert(stack,v)
                    cache[node] = cur_index+1
                    break
                else
                    output_str = output_str .. string.rep(TAB_CHAR,depth*indentation) .. key .." = '"..tostring(v).."'"
                end

                if (cur_index == size) then
                    output_str = output_str .. NEW_LINE .. string.rep(TAB_CHAR,(depth-1)*indentation) .."}"
                else
                    output_str = output_str ..","
                end
            else
                -- close the table
                if (cur_index == size) then
                    output_str = output_str .. NEW_LINE .. string.rep(TAB_CHAR,(depth-1)*indentation) .."}"
                end
            end

            cur_index = cur_index + 1
        end

        if (size == 0) then
            output_str = output_str .. NEW_LINE .. string.rep(TAB_CHAR,(depth-1)*indentation) .."}"
        end

        if (#stack > 0) then
            node = stack[#stack]
            stack[#stack] = nil
            depth = cache[node] == nil and depth + 1 or depth - 1
        else
            break
        end
    end

    -- This is necessary for working with HUGE tables otherwise we run out of memory using concat on huge strings
    table.insert(output,output_str)
    output_str = table.concat(output)

    return output_str

end

然后:

1
2
3
4
5
6
7
8
9
print(dump_table_to_string("AA", true,3))

print(dump_table_to_string({"AA","BB"}, true,3))

print(dump_table_to_string({"AA","BB"}))

print(dump_table_to_string({"AA","BB"},false))

print(dump_table_to_string({"AA","BB",{22,33}},true,2))

给予:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
only table type is supported, got string

{
   [1] = 'AA',
   [2] = 'BB'
}

{
 [1] = 'AA',
 [2] = 'BB'
}

{[1] = 'AA',[2] = 'BB'}

{
  [1] = 'AA',
  [2] = 'BB',
  [3] = {
    [1] = 22,
    [2] = 33
  }
}

现在函数 print 可以打印(平面)表格了!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
oprint = print -- origin print
print = function (...)
    if type(...) =="table" then
        local str = ''
        local amount = 0
        for i,v in pairs(...) do
            amount=amount+1
            local pre = type(i) =="string" and i.."=" or""
            str = str .. pre..tostring(v) .."\\t"
        end
        oprint('#'..amount..':', str)
    else
        oprint(...)
    end
end

例如:

1
print ({x=7, y=9, w=11, h="height", 7, 8, 9})

打印:

#7: 7 8 9 y=9 x=7 h=height w=11

同样的方法可以只是新函数tostring:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
otostring = tostring -- origin tostring
tostring = function (...)
    if type(...) =="table" then
        local str = '{'
        for i,v in pairs(...) do
            local pre = type(i) =="string" and i.."=" or""
            str = str .. pre..tostring(v) ..","
        end
        str = str:sub(1, -3)
        return str..'}'
    else
        return otostring(...)
    end
end