标签:lua stack overflow 尾递归
原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>版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:lua stack overflow 尾递归
原文地址:http://blog.csdn.net/booirror/article/details/47281385