【问题标题】:loading serialized data into a table将序列化数据加载到表中
【发布时间】:2011-08-22 23:06:20
【问题描述】:

对于to another question 的答案,我想将一些序列化的 lua 代码加载到表中。要加载的字符串是这样的形式:

SavedVars = {  }
SavedStats = {  }

(其中每个 {...} 可能是任何 Lua 表达式,包括带有嵌套数据的表构造函数。我假设它没有调用任何(全局)函数或使用全局变量。

我最终想要的是这种形式的表格:

{ ["SavedVar"] = { }, ["SavedStats"] = { } }

之后我不想有全局变量SavedVars。 如何最优雅地做到这一点?

(我已经找到了解决方案,但也许有人有更好的解决方案。)

【问题讨论】:

  • 你知道{ ["SavedVar"]={}, ["SavedStats"]={} }也可以写成{ SavedVar={}, SavedStats={} }吗?
  • @lhf:是的,但这在这里无关紧要——我只是想要 Lua 中的表,而不是字符串输出。

标签: serialization lua deserialization


【解决方案1】:

这是我的解决方案:

-- loads a string to a table.
--   this executes the string with the environment of a new table, and then
--   returns the table.
--
-- The code in the string should not need any variables it does not declare itself,
-- as these are not available on runtime. It runs in a really empty environment.
function loadTable(data)
   local table = {}
   local f = assert(loadstring(data))
   setfenv(f, table)
   f()
   return table
end

它使用loadstring 加载数据字符串,然后使用setfenv 将函数的全局环境修改为新表。然后调用加载的函数一次填充这个表(而不是全局环境),然后我们可以返回。

将环境设置为新表会导致代码根本无法使用任何全局数据。我认为这是对代码进行沙箱处理的好方法,但如果不需要,您可以在之前填充表或为其提供一些元表(但在返回表之前取消设置)。

此加载函数也适用于在Saving Tables with Cycles 中生成的序列化数据。

【讨论】:

    猜你喜欢
    • 2013-01-02
    • 2015-06-23
    • 1970-01-01
    • 1970-01-01
    • 2015-06-06
    • 1970-01-01
    • 1970-01-01
    • 2017-03-08
    • 2017-02-09
    相关资源
    最近更新 更多