原Lua打印table有个很致命的问题,递归深度过大会导致栈溢出(stack overflow)。
首先,需要明白,lua里出现栈溢出有以下情况:
“too many arguments”,
“assume array is smaller than 2^40 “,
“string slice too long”,
“too many captures”,
“too many arguments to script”,
“too many nested functions”
那么问题来了,如何才能不出现栈溢出呢?
我想,方法应该不止一种,我使用的是尾递归,Lua里使用尾递归是不会出现栈溢出的,不管递归深度有多大。下面是修改后的代码:
<span style="font-family:Courier New;">function getIndentSpace(indent) local str = "" for i =1, indent do str = str .. " " end return str end function newLine(indent) local str = "\n" str = str .. getIndentSpace(indent) return str end function createKeyVal(key, value, bline, deep, indent) return str end function getkeyvalstr(iters, iterIdx, bline, deep, indent, bstr, estr) local key ,value = iters[iterIdx]() while key == nil do if iterIdx == 1 then return bstr .. estr else iterIdx = iterIdx - 1 key ,value = iters[iterIdx]() local right = ","; if true then if bline[deep] then indent = indent-4 right = right .. newLine(indent) .. "}" else right = right .. "}" end end bstr = bstr .. right deep = deep - 1 end end local left = "" local kv = ""; if (bline[deep]) then kv = kv .. newLine(indent) end if type(key) == "string" then kv = kv.. key .. " = " end if type(value) == "table" then deep = deep + 1 if bline[deep] then kv = kv ..newLine(indent) .. "{" indent = indent + 4 else kv = kv .. "{" end local iter = nextKeyValue(value) iterIdx = iterIdx+1 iters[iterIdx] = iter elseif type(value) == "string" then kv = kv .. '"' .. tostring(value) .. '"' else kv = kv ..tostring(value) end left = left .. kv bstr = bstr .. left return getkeyvalstr(iters,iterIdx, bline, deep, indent, bstr, estr); end function nextKeyValue(t) local iter, tb, key, value = pairs(t) return function() key, value = iter(tb, key); return key, value end end function getTableStr(t, bline, deep, indent) local iter = nextKeyValue(t) local iters = {} local idx = 1 iters[idx] = iter local left local right = "," if bline[deep] then left = newLine(indent) .. "{" indent = indent + 4; else left = "{" end left = left .. getkeyvalstr(iters, idx, bline, deep, indent, "", "") if bline[deep] then indent = indent-4 right = right .. newLine(indent) .. "}" else right = right .. "}" end return left .. right end function printtable(t) if type(t) ~= "table" then return end local str = getTableStr(t, {true, true, true}, 1, 0) print(str) end</span>
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-11-05 19:02:01