此第一版是為 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