lua中loadstring的使用与有环表的序列化

本文介绍了一种用于处理复杂表数据的序列化方法,包括如何使用LoadString进行加载和处理序列化后的数据,同时提供了最高递归深度限制以避免内存溢出问题。

我使用LoadString是总是想让他处理一大些事后返回,可是总是不成功,原来是我的语句间隔不对(要用';'或什么都不用),换成分号后就行了我写的可以嵌套的table表序列化函数,而且做了最深的递归深度限制,序列化结果为字符串,以后你想怎样处理就怎样处理,方便多了。而且使用时直接loadstring就行了,方便做异常处理

function SerializeUltra(tbl,saved,TopName)--序列化table函数
	local saved = saved or {}
	local TopName = TopName or 'temp'
	local function BasicSerialze(o)
		if type(o) == type(0) then
		return tostring(o)
		else
		return string.format("%q",o)--格式化处理
		end
	end
	local ret = {}
	local function Serialize(tbl,saved,name,level)
		local name = name or "temp"
		local level = level or 0
		--print (level)
		level = level + 1
		if level > 20 then --限制为最高20层table
			error("too deep to servialize!")
		end
		table.insert(ret,name..' = ')
		if type(tbl) == "table" then
			if saved[tbl] then
				table.insert(ret,saved[tbl]..";\n")
			else
				saved[tbl] = name
				table.insert(ret,"{};\n")
				for k,v in pairs(tbl) do
					local _k = BasicSerialze(k)
					if _k == nil then
						error("servialize with an error key!")
					end
					local tname = string.format("%s[%s]",name,_k)
					Serialize(v,saved,tname,level)
				end
			end
		else
			table.insert(ret,string.format("%s;\n",BasicSerialze(tbl)))
		end
	end
	Serialize(tbl,saved,TopName)
	return string.format("local %sreturn %s",table.concat(ret),TopName)
end

示例程序:

userObj = {
	[1] = {
		['id']=1,
		['name']='ice',
		['grade']=0,
		['sumGrade']=0,
		},
}
userObj[2] = userObj[1]
strTbl=SerializeUltra(userObj)
print (strTbl)
zz=loadstring(strTbl)()
print(zz[2].name)

运行结果:

local temp = {};
temp[1] = {};
temp[1]["id"] = 1;
temp[1]["sumGrade"] = 0;
temp[1]["name"] = "ice";
temp[1]["grade"] = 0;
temp[2] = temp[1];
return temp
ice


详细描述Lua和C之间相互传递Table类型数据 /* ====================================================== */ // 遍历Lua传入的Table类型参数, 获取它的Key/Value, 其关键操作是 lua_next() // lua_next() 返回1示读取成功,返回0示已经没有数据可读了 // lua_next() 会使用栈顶元素作为Key去定位本次需要取出Table里面的那个值对 // 如果Key=nil, 那就示本次取出的是第一个元素 // 它会先将当前的这个Key弹出,然后将本次取出的Key/Value压入栈, Value在栈顶 // 一个比较隐晦的处理就是, 我们不应直接使用lua_tostring(L, -2)来读取Key // 因为lua_tostring()在Key类型不是字符串时, 它会修改栈上的Key数据 // 这样, 下次调用lua_next()时, 就会因为Key被修改了而导致错误 // 为此,先调用lua_pushvalue(L, -2),将它Copy一份到栈顶,对这个Copy进行lua_tostring() // 读取Key,Value到C变量里面后,将Value和Copy弹出,留着Key在栈顶,给下次lua_next()用 // // 指令及栈图变化如下: (假如Table的栈下标是Index) // 0. 刚进入函数时 ...Table, ... <--- 这里栈顶 // 1. lua_pushnil(L) ...Table, ..., nil <--- 这里栈顶 // 2. lua_next(L, Index) ...Table, ..., Key, Value <--- 这里栈顶 // 3. lua_pushvalue(L, -2) ...Table, ..., Key, Value, KeyCopy <--- 这里栈顶 // 4. lua_pop(L, 2), ...Table, ..., Key <--- 这里栈顶 // ... 如此重复2,3,4 // N. lua_next(L, Index)返回0 ...Table, ... <--- 这里栈顶 /* ====================================================== */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值