第一版是为 Lua 5.0 编写的。虽然在很大程度上仍然适用于后续版本,但有一些不同之处。
第四版针对 Lua 5.3,可在 Amazon 和其他书店购买。
购买本书,您还将帮助支持 Lua 项目


12.1 – 序列化

我们经常需要序列化一些数据,即,将数据转换为字节或字符流,以便我们可以将其保存到文件中或通过网络连接发送。我们可以将序列化数据表示为 Lua 代码,这样,当我们运行代码时,它会将保存的值重建到读取程序中。

通常,如果我们想要恢复全局变量的值,我们的块将类似于 varname = <exp>,其中 <exp> 是创建该值的 Lua 代码。varname 是简单的一部分,因此让我们看看如何编写创建值的代码。对于数值,任务很简单

    function serialize (o)
      if type(o) == "number" then
        io.write(o)
      else ...
    end
对于字符串值,一种朴素的方法类似于
    if type(o) == "string" then
      io.write("'", o, "'")
但是,如果字符串包含特殊字符(例如引号或换行符),则生成的代码将不是有效的 Lua 程序。在这里,您可能很想通过更改引号来解决此问题
    if type(o) == "string" then
      io.write("[[", o, "]]")
不要这样做!双方括号用于手写字符串,而不是自动生成字符串。如果恶意用户设法指导您的程序保存类似于 " ]]..os.execute('rm *')..[[ " 的内容(例如,她可以将其字符串作为她的地址提供),您的最终块将是
    varname = [[ ]]..os.execute('rm *')..[[ ]]
您将尝试加载此“数据”时会感到惊讶。

为了安全地引用任意字符串,标准 string 库中的 format 函数提供了 "%q" 选项。它用双引号包围字符串,并正确转义字符串中的双引号、换行符和其他一些字符。使用此功能,我们的 serialize 函数现在看起来像这样

    function serialize (o)
      if type(o) == "number" then
        io.write(o)
      elseif type(o) == "string" then
        io.write(string.format("%q", o))
      else ...
    end