码迷,mamicode.com
首页 > 其他好文 > 详细

Lua打印table升级版

时间:2015-08-04 21:08:48      阅读:278      评论:0      收藏:0      [点我收藏+]

标签: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打印table升级版

标签:lua   stack overflow   尾递归   

原文地址:http://blog.csdn.net/booirror/article/details/47281385

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!