我是一名開發者,我讀程式碼,我寫程式碼,我寫會寫程式碼的程式碼,我寫會寫出供其它程式碼讀的程式碼的程式碼。這些都非常火星語,但是有其美妙之處。然而,最後一點,寫會寫出供其它程式碼讀的程式碼的程式碼,可以很快變得比這段文字更費解。有很多方法可以做到這一點。一種不那麼複雜而且開發者社群最愛的方式是資料序列化。對於那些不了解我剛剛拋給你的時髦詞的人,資料序列化是從一個系統獲取一些資訊,將其轉換為其它系統可以讀取的格式,然後將其傳遞給其它系統的過程。
雖然資料序列化格式多到可以埋葬哈利法塔,但它們大多分為兩類:
很難兩全其美,因為人類喜歡讓我們更具表現力的鬆散型別和靈活格式標準,而機器傾向於被確切告知一切事情而沒有二義性和細節缺失,並且認為“嚴格規範”才是它們最愛的口味。
由於我是一名 web 開發者,而且我們是一個建立網站的機構,我們將堅持使用 web 系統可以理解或不需要太多努力就能理解的特殊格式,而且對人類可讀性特別有用的格式:XML、JSON、TOML、CSON 以及 YAML。每個都有各自的優缺點和適當的用例場景。
回到網際網路的早期,一些非常聰明的傢伙決定整合一種讓每個系統都能理解的標準語言,並創造性地將其命名為標準通用標示語言(簡稱 SGML)。SGML 非常靈活,發布者也很好地定義了它。它成為了 XML、SVG 和 HTML 等語言之父。所有這三個都符合 SGML 規範,可是它們都是規則更嚴格、靈活性更少的子集。
最終,人們開始看到非常小、簡潔、易讀且易於生成的資料的好處,這些資料可以在系統之間以程式設計的方式共用,而開銷很小。大約在那個時候,JSON 誕生了並且能夠滿足所有的需求。而另一方面,其它語言也開始出現以處理更多的專業用例,如 CSON,TOML 和 YAML。
原本,XML 語言非常靈活且易於編寫,但它的缺點是冗長,人類難以閱讀、計算機非常難以讀取,並且有很多語法對於傳達資訊並不是完全必要的。
今天,它在 web 上的資料序列化的用途已經消失了。除非你在編寫 HTML 或者 SVG,否則你不太能在許多其它地方看到 XML。一些過時的系統今天仍在使用它,但是用它傳遞資料往往太重了。
我已經可以聽到 XML 老爺爺開始在它們的石碑上亂寫為什麼 XML 是了不起的,所以我將提供一個小小的補充:XML 可以很容易地由系統和人讀寫。然而,真的,我的意思是荒謬的,很難建立一個可以規範的讀取它的系統。這是一個簡單美觀的 XML 範例:
<book id="bk101"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre><price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applicationswith XML.</description></book>
太棒了。易於閱讀、理解、寫入,也容易編碼一個可以讀寫它的系統。但請考慮這個例子:
<!DOCTYPE r [ <!ENTITY y "a]>b"> ]><r><a b="&y;>" /><![CDATA[[a>b <a>b <a]]><?x <a> <!-- <b> ?> c --> d</r>
這上面是 100% 有效的 XML。幾乎不可能閱讀、理解或推理。編寫可以使用和理解這個的程式碼將花費至少 36 根頭髮和 248 磅咖啡渣。我們沒有那麼多時間或咖啡,而且我們大多數老程式設計師們現在都是禿頭。所以,讓它活在我們的記憶裡,就像 css hacks、IE 6 瀏覽器 和真空管一樣好了。
好吧,我們都同意,XML = 差勁。那麼,好的替代品是什麼?JavaScript 物件表示法,簡稱 JSON。JSON(讀起來像 Jason 這個名字) 是 Brendan Eich 發明的,並且得到了偉大而強力的 JavaScript 意見領袖 Douglas Crockford 的推廣。它現在幾乎用在任何地方。這種格式很容易由人和機器編寫,按規範中的嚴格規則解析也相當容易,並且靈活 —— 允許深層巢狀資料,支援所有的原始資料型別,及將集合解釋為陣列或物件。JSON 成為了將資料從一個系統傳輸到另一個系統的事實標準。幾乎所有語言都有內建讀寫它的功能。
JSON語法很簡單。方括號表示陣列,花括號表示記錄,由冒號分隔的兩個值分別表示屬性或“鍵”(在左邊)、值(在右邊)。所有鍵必須用雙引號括起來:
{ "books": [ { "id": "bk102", "author": "Crockford, Douglas", "title": "JavaScript: The Good Parts", "genre": "Computer", "price": 29.99, "publish_date": "2008-05-01", "description": "Unearthing the Excellence in JavaScript" } ] }
這對你來說應該是完全有意義的。它簡潔明瞭,並且從 XML 中刪除了大量額外廢話,並傳達相同數量的資訊。JSON 現在是王道,本文剩下的部分會介紹其它語言格式,這些格式只不過是 JSON 的簡化版,嘗試讓其更簡潔或對人類更易讀,可結構還是非常相似的。
TOML(Tom 的顯而易見的最小化語言)允許以相當快捷、簡潔的方式定義深層巢狀的資料結構。名字中的 Tom 是指發明者 Tom Preston Werner,他是一位活躍於我們行業的創造者和軟體開發人員。與 JSON 相比,語法有點尷尬,更類似 ini 檔案。這不是一個糟糕的語法,但是需要一些時間適應。
[[books]]id = 'bk101'author = 'Crockford, Douglas'title = 'JavaScript: The Good Parts'genre = 'Computer'price = 29.99publish_date = 2008-05-01T00:00:00+00:00description = 'Unearthing the Excellence in JavaScript'
TOML 中整合了一些很棒的功能,例如多行字串、保留字元的自動跳脫、日期、時間、整數、浮點數、科學記數法和“表擴充套件”等資料型別。最後一點是特別的,是 TOML 如此簡潔的原因:
[a.b.c]d = 'Hello'e = 'World'
以上擴充套件到以下內容:
{ "a": { "b": { "c": { "d": "Hello" "e": "World" } } }}
使用 TOML,你可以肯定在時間和檔案長度上會節省不少。很少有系統使用它或非常類似的東西作為設定,這是它最大的缺點。根本沒有很多語言或庫可以用來解釋 TOML。
首先,有兩個 CSON 規範。 一個代表 CoffeeScript Object Notation,另一個代表 Cursive Script Object Notation。後者不經常使用,所以我們不會關注它。我們只關注 CoffeeScript。
CSON 需要一點介紹。首先,我們來談談 CoffeeScript。CoffeeScript 是一種通過執行編譯器生成 JavaScript 的語言。它允許你以更加簡潔的語法編寫 JavaScript 並轉譯成實際的 JavaScript,然後你可以在你的 web 應用程式中使用它。CoffeeScript 通過刪除 JavaScript 中必需的許多額外語法,使編寫 JavaScript 變得更容易。CoffeeScript 擺脫的一個大問題是花括號 —— 不需要它們。同樣,CSON 是沒有大括號的 JSON。它依賴於縮排來確定資料的層次結構。CSON 非常易於讀寫,並且通常比 JSON 需要更少的程式碼行,因為沒有括號。
CSON 還提供一些 JSON 不提供的額外細節。多行字串非常容易編寫,你可以通過使用 #
符號開始一行來輸入注釋,並且不需要用逗號分隔鍵值對。
books: [ id: 'bk102' author: 'Crockford, Douglas' title: 'JavaScript: The Good Parts' genre: 'Computer' price: 29.99 publish_date: '2008-05-01' description: 'Unearthing the Excellence in JavaScript']
這是 CSON 的大問題。它是 CoffeScript 物件表示法。也就是說你要用 CoffeeScript 解析/標記化/lex/轉譯或其它方式來使用 CSON。CoffeeScript 是讀取資料的系統。如果資料序列化的目的是允許資料從一個系統傳遞到另一個系統,這裡我們有一個只能由單個系統讀取的資料序列化格式,這使得它與防火火柴、防水海綿或者叉匙惱人的脆弱叉子部分一樣有用。
如果這種格式被其它系統也採用,那它在開發者世界中可能非常有用。但到目前為止這基本上沒有發生,所以在 PHP 或 JAVA 等替代語言中使用它是不行的。
開發人員感到高興,因為 YAML 來自一個 Python 的貢獻者。YAML 具有與 CSON 相同的功能集和類似的語法,有一系列新功能,以及幾乎所有 web 程式語言都可用的解析器。它還有一些額外的功能,如迴圈參照、軟包裝、多行鍵、型別轉換標籤、二進位制資料、物件合併和集合對映。它具有非常好的可讀性和可寫性,並且是 JSON 的超集,因此你可以在 YAML 中使用完全合格的 JSON 語法並且一切正常工作。你幾乎不需要引號,它可以解釋大多數基本資料型別(字串、整數、浮點數、布林值等)。
books: - id: bk102 author: Crockford, Douglas title: 'JavaScript: The Good Parts' genre: Computer price: 29.99 publish_date: !!str 2008-05-01 description: Unearthing the Excellence in JavaScript
業界的年輕人正在迅速採用 YAML 作為他們首選的資料序列化和系統設定格式。他們這樣做很機智。YAML 具有像 CSON 一樣簡潔的所有好處,以及與 JSON 一樣的資料型別解釋的所有功能。YAML 像加拿大人容易相處一樣容易閱讀。
YAML 有兩個問題,對我而言,第一個是大問題。在撰寫本文時,YAML 解析器尚未內建於多種語言,因此你需要使用第三方庫或擴充套件來為你選擇的語言解析 .yaml 檔案。這不是什麼大問題,可似乎大多數為 YAML 建立解析器的開發人員都選擇隨機將“附加功能”放入解析器中。有些允許標記化,有些允許鏈參照,有些甚至允許內聯計算。這一切都很好(某種意義上),只是這些功能都不是規範的一部分,因此很難在其他語言的其他解析器中找到。這導致系統限定,你最終遇到了與 CSON 相同的問題。如果你使用僅在一個解析器中找到的功能,則其他解析器將無法解釋輸入。大多數這些功能都是無意義的,不屬於資料集,而是屬於你的應用程式邏輯,因此最好簡單地忽略它們和編寫符合規範的 YAML。
第二個問題是很少有解析器完全實現規範。所有的基本要素都有,但是很難找到一些更複雜和更新的東西,比如軟包裝、文件標記和首選語言的迴圈參照。我還沒有看到對這些東西的剛需,所以希望它們不讓你很失望。考慮到上述情況,我傾向於保持 1.1 規範 中呈現的更成熟的功能集,而避免在 1.2 規範 中找到的新東西。然而,程式設計是一個不斷發展的怪獸,所以當你讀完這篇文章時,你或許就可以使用 1.2 規範了。
這是最後一段話。每個序列化語言都應該以個案標準的方式評價。當涉及機器的可讀性時,有些無出其右。對於人類可讀性,有些名至實歸,有些只是金玉其外。以下是最終細分:如果你要編寫供其他程式碼閱讀的程式碼,請使用 YAML。如果你正在編寫能寫出供其他程式碼讀取的程式碼的程式碼,請使用 JSON。最後,如果你正在編寫將程式碼轉譯為供其他程式碼讀取的程式碼的程式碼,請重新考慮你的人生選擇。