一段超級嚴肅的關於樣本序列化的集合、子集和超集的文字

我是一名開發者,我讀代碼,我寫代碼,我寫會寫代碼的代碼,我寫會寫出供其它代碼讀的代碼的代碼。這些都非常火星語,但是有其美妙之處。然而,最後一點,寫會寫出供其它代碼讀的代碼的代碼,可以很快變得比這段文字更費解。有很多方法可以做到這一點。一種不那麼複雜而且開發者社區最愛的方式是數據序列化。對於那些不了解我剛剛拋給你的時髦詞的人,數據序列化是從一個系統獲取一些信息,將其轉換為其它系統可以讀取的格式,然後將其傳遞給其它系統的過程。

雖然數據序列化格式多到可以埋葬哈利法塔,但它們大多分為兩類:

  • 易於人類讀寫,
  • 易於機器讀寫。

很難兩全其美,因為人類喜歡讓我們更具表現力的鬆散類型和靈活格式標準,而機器傾向於被確切告知一切事情而沒有二義性和細節缺失,並且認為「嚴格規範」才是它們最愛的口味。

由於我是一名 web 開發者,而且我們是一個創建網站的機構,我們將堅持使用 web 系統可以理解或不需要太多努力就能理解的特殊格式,而且對人類可讀性特別有用的格式:XML、JSON、TOML、CSON 以及 YAML。每個都有各自的優缺點和適當的用例場景。

事實最先

回到互聯網的早期,一些非常聰明的傢伙決定整合一種讓每個系統都能理解的標準語言,並創造性地將其命名為 標準通用標記語言(Standard Generalized Markup Language)(簡稱 SGML)。SGML 非常靈活,發布者也很好地定義了它。它成為了 XML、SVG 和 HTML 等語言之父。所有這三個都符合 SGML 規範,可是它們都是規則更嚴格、靈活性更少的子集。

最終,人們開始看到非常小、簡潔、易讀且易於生成的數據的好處,這些數據可以在系統之間以編程的方式共享,而開銷很小。大約在那個時候,JSON 誕生了並且能夠滿足所有的需求。而另一方面,其它語言也開始出現以處理更多的專業用例,如 CSON,TOML 和 YAML。

XML:不行了

原本,XML 語言非常靈活且易於編寫,但它的缺點是冗長,人類難以閱讀、計算機非常難以讀取,並且有很多語法對於傳達信息並不是完全必要的。

今天,它在 web 上的數據序列化的用途已經消失了。除非你在編寫 HTML 或者 SVG,否則你不太能在許多其它地方看到 XML。一些過時的系統今天仍在使用它,但是用它傳遞數據往往太重了。

我已經可以聽到 XML 老爺爺開始在它們的石碑上亂寫為什麼 XML 是了不起的,所以我將提供一個小小的補充:XML 可以很容易地由系統和人讀寫。然而,真的,我的意思是荒謬的,很難創建一個可以規範的讀取它的系統。這是一個簡單美觀的 XML 示例:

<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developers Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications
with 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 瀏覽器 和真空管一樣好了。

JSON:並列聚會

好吧,我們都同意,XML = 差勁。那麼,好的替代品是什麼? JavaScript 對象表示法(JavaScript Object Notation),簡稱 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: 縮短到徹底的利他主義

TOML( Tom 的顯而易見的最小化語言(Tom』s Obvious, Minimal Language))允許以相當快捷、簡潔的方式定義深層嵌套的數據結構。名字中的 Tom 是指發明者 Tom Preston Werner,他是一位活躍於我們行業的創造者和軟體開發人員。與 JSON 相比,語法有點尷尬,更類似 ini 文件。這不是一個糟糕的語法,但是需要一些時間適應。

[[books]]
id = bk101
author = Crockford, Douglas
title = JavaScript: The Good Parts
genre = Computer
price = 29.99
publish_date = 2008-05-01T00:00:00+00:00
description = Unearthing the Excellence in JavaScript

TOML 中集成了一些很棒的功能,例如多行字元串、保留字元的自動轉義、日期、時間、整數、浮點數、科學記數法和「表擴展」等數據類型。最後一點是特別的,是 TOML 如此簡潔的原因:

[a.b.c]
d = Hello
e = World

以上擴展到以下內容:

{
"a": {
"b": {
"c": {
"d": "Hello"
"e": "World"
}
}
}
}

使用 TOML,你可以肯定在時間和文件長度上會節省不少。很少有系統使用它或非常類似的東西作為配置,這是它最大的缺點。根本沒有很多語言或庫可以用來解釋 TOML。

CSON: 特定系統所包含的簡單樣本

首先,有兩個 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 Object Notation)。也就是說你要用 CoffeeScript 解析/標記化/lex/轉譯或其它方式來使用 CSON。CoffeeScript 是讀取數據的系統。如果數據序列化的目的是允許數據從一個系統傳遞到另一個系統,這裡我們有一個只能由單個系統讀取的數據序列化格式,這使得它與防火火柴、防水海綿或者叉匙惱人的脆弱叉子部分一樣有用。

如果這種格式被其它系統也採用,那它在開發者世界中可能非常有用。但到目前為止這基本上沒有發生,所以在 PHP 或 JAVA 等替代語言中使用它是不行的。

YAML:年輕人的呼喊

開發人員感到高興,因為 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 規範了。

最終哲學

這是最後一段話。每個序列化語言都應該以個案標準的方式評價。當涉及機器的可讀性時,有些 無出其右(the bee』s knees)。對於人類可讀性,有些 名至實歸(the cat』s meow),有些只是 金玉其外(gilded turds)。以下是最終細分:如果你要編寫供其他代碼閱讀的代碼,請使用 YAML。如果你正在編寫能寫出供其他代碼讀取的代碼的代碼,請使用 JSON。最後,如果你正在編寫將代碼轉譯為供其他代碼讀取的代碼的代碼,請重新考慮你的人生選擇。


via: zionandzion.com/json-vs

作者:Tim Anderson 選題:lujun9972 譯者:GraveAccent 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出


推薦閱讀:
相关文章