LUA教程保存带循环的table |
您所在的位置:网站首页 › lua中table的用法 › LUA教程保存带循环的table |
针对普通拓扑概念上的带有循环表和共享子表的table,我们需要另外一种不同的方法来处理。构造器不能很好地解决这种情况,我们不使用。为了表示循环我们需要将表名记录下来,下面我们的函数有两个参数:table和对应的名字。另外,我们还必须记录已经保存过的table以防止由于循环而被重复保存。我们使用一个额外的table来记录保存过的表的轨迹,这个表的下表索引为table,而值为对应的表名。 我们做一个限制:要保存的table只有一个字符串或者数字关键字。下面的这个函数序列化基本类型并返回结果。 function basicSerialize (o) if type(o) == "number" then return tostring(o) else -- assume it is a string return string.format("%q", o) end end关键内容在接下来的这个函数,saved这个参数是上面提到的记录已经保存的表的踪迹的table。 function save (name, value, saved) saved = saved or {} -- initial value io.write(name, " = ") if type(value) == "number" or type(value) == "string" then io.write(basicSerialize(value), "\n") elseif type(value) == "table" then if saved[value] then -- value already saved? -- use its previous name io.write(saved[value], "\n") else saved[value] = name -- save name for next time io.write("{}\n") -- create a new table for k,v in pairs(value) do -- save its fields local fieldname = string.format("%s[%s]", name, basicSerialize(k)) save(fieldname, v, saved) end end else error("cannot save a " .. type(value)) end end保存的table为: a = {x=1, y=2; {3,4,5}} a[2] = a -- cycle a.z = a[1] -- shared sub-table调用save('a', a)之后结果为: a = {} a[1] = {} a[1][1] = 3 a[1][2] = 4 a[1][3] = 5 a[2] = a a["y"] = 2 a["x"] = 1 a["z"] = a[1](实际的顺序可能有所变化,它依赖于table遍历的顺序,不过,这个算法保证了一个新的定义中需要的前面的节点都已经被定义过) 如果我们想保存带有共享部分的表,我们可以使用同样table的saved参数调用save函数,例如我们创建下面两个表: a = {{"one", "two"}, 3} b = {k = a[1]}保存它们: save('a', a) save('b', b)结果将分别包含相同部分: a = {} a[1] = {} a[1][1] = "one" a[1][2] = "two" a[2] = 3 b = {} b["k"] = {} b["k"][1] = "one" b["k"][2] = "two"然而如果我们使用同一个saved表来调用save函数: local t = {} save('a', a, t) save('b', b, t)结果将共享相同部分: a = {} a[1] = {} a[1][1] = "one" a[1][2] = "two" a[2] = 3 b = {} b["k"] = a[1]上面这种方法是Lua中常用的方法,当然也有其他一些方法可以解决问题。比如,我们可以不使用全局变量名来保存,即使用封包,用chunk构造一个local值然后返回之;通过构造一张表,每张表名与其对应的函数对应起来等。Lua给予你权力,由你决定如何实现。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |