回到简体

This commit is contained in:
chai2010
2016-02-15 11:06:34 +08:00
parent 9e878f9944
commit 2b37b23285
177 changed files with 2354 additions and 2354 deletions

View File

@@ -1,10 +1,10 @@
## 12.4. 示例: 編碼S表
## 12.4. 示例: 编码S表
Display是一個用於顯示結構化數據的調試工具,但是它不能任意的Go語言對象編碼爲通用消息然後用於進程間通信。
Display是一个用于显示结构化数据的调试工具,但是它不能任意的Go语言对象编码为通用消息然后用于进程间通信。
正如我在4.5中中看到的Go言的標準庫支持了包括JSON、XML和ASN.1等多種編碼格式。有另一依然被泛使用的格式是S表式格式,采用似Lisp言的法。但是和其他編碼格式不同的是Go言自帶的標準庫併不支持S表式,主要是因爲它沒有一個公認的標準規范。
正如我在4.5中中看到的Go言的标准库支持了包括JSON、XML和ASN.1等多种编码格式。有另一依然被广泛使用的格式是S表式格式,采用似Lisp言的法。但是和其他编码格式不同的是Go言自带的标准库并不支持S表式,主要是因为它没有一个公认的标准规范。
在本中,我們將定義一個包用於將Go言的對象編碼爲S表式格式,它支持以下結構
在本中,我们将定义一个包用于将Go言的对象编码为S表式格式,它支持以下结构
```
42 integer
@@ -13,13 +13,13 @@ foo symbol (an unquoted name)
(1 2 3) list (zero or more items enclosed in parentheses)
```
爾型習慣上使用t符表示true空列表或nil符表示false但是爲了簡單起見,我們暫時忽略布爾類型。同忽略的有chan管道和函,因爲通過反射併無法知道它們的確切狀態。我忽略的還浮點數、複數和interface。支持它們是練習12.3的任
尔型习惯上使用t符表示true空列表或nil符表示false但是为了简单起见,我们暂时忽略布尔类型。同忽略的有chan管道和函,因为通过反射并无法知道它们的确切状态。我忽略的还浮点数、复数和interface。支持它们是练习12.3的任
們將Go言的類型編碼爲S表式的方法如下。整和字符串以自然的方式編碼。Nil值編碼爲nil符號。數組和slice被編碼爲一個列表。
们将Go言的类型编码为S表式的方法如下。整和字符串以自然的方式编码。Nil值编码为nil符号。数组和slice被编码为一个列表。
結構體被編碼爲成員對象的列表,每個成員對象對應一個個僅有兩個元素的子列表,其中子列表的第一元素是成的名字,子列表的第二元素是成的值。Map被編碼爲鍵值對的列表。傳統S表式使用點狀符號列表(key . value)結構來表示key/value,而不是用一個含雙元素的列表,不過爲了簡單我們忽略了點狀符號列表。
结构体被编码为成员对象的列表,每个成员对象对应一个个仅有两个元素的子列表,其中子列表的第一元素是成的名字,子列表的第二元素是成的值。Map被编码为键值对的列表。传统S表式使用点状符号列表(key . value)结构来表示key/value,而不是用一个含双元素的列表,不过为了简单我们忽略了点状符号列表。
編碼是由一encode遞歸函數完成,如下所示。它的結構本質上和前面的Display函數類似:
编码是由一encode递归函数完成,如下所示。它的结构本质上和前面的Display函数类似:
<u><i>gopl.io/ch12/sexpr</i></u>
```Go
@@ -93,7 +93,7 @@ func encode(buf *bytes.Buffer, v reflect.Value) error {
}
```
Marshal函數是對encode的保以保持和encoding/...下其它包有着相似的API
Marshal函数是对encode的保以保持和encoding/...下其它包有着相似的API
```Go
// Marshal encodes a Go value in S-expression form.
@@ -106,7 +106,7 @@ func Marshal(v interface{}) ([]byte, error) {
}
```
下面是Marshal12.3的strangelove變量編碼後的結果:
下面是Marshal12.3的strangelove变量编码后的结果:
```
((Title "Dr. Strangelove") (Subtitle "How I Learned to Stop Worrying and Lo
@@ -118,7 +118,7 @@ ge C. Scott") ("Brig. Gen. Jack D. Ripper" "Sterling Hayden") ("Maj. T.J. \
omin.)" "Best Picture (Nomin.)")) (Sequel nil))
```
個輸出編碼爲一行中以減少輸出的大小,但是也很難閲讀。這里有一個對S表式格式化的定。編寫一個S表式的格式化函數將作爲一個具有挑性的練習任務;不 http://gopl.io 也提供了一個簡單的版本。
个输出编码为一行中以减少输出的大小,但是也很难阅读。这里有一个对S表式格式化的定。编写一个S表式的格式化函数将作为一个具有挑性的练习任务;不 http://gopl.io 也提供了一个简单的版本。
```
((Title "Dr. Strangelove")
@@ -137,16 +137,16 @@ omin.)" "Best Picture (Nomin.)")) (Sequel nil))
(Sequel nil))
```
和fmt.Print、json.Marshal、Display函數類sexpr.Marshal函數處理帶環的數據結構也會陷入死循
和fmt.Print、json.Marshal、Display函数类sexpr.Marshal函数处理带环的数据结构也会陷入死循
在12.6中,我們將給出S表式解器的實現步驟,但是在那之前,我們還需要先了解如果通反射技術來更新程序的量。
在12.6中,我们将给出S表式解器的实现步骤,但是在那之前,我们还需要先了解如果通反射技术来更新程序的量。
**練習 12.3** 實現encode函缺少的分支。將布爾類型編碼爲t和nil點數編碼爲Go言的格式,複數1+2i編碼爲#C(1.0 2.0)格式。接口編碼爲類型名和值,例如("[]int" (1 2 3)),但是這個形式可能造成歧reflect.Type.String方法對於不同的型可能返相同的果。
**练习 12.3** 实现encode函缺少的分支。将布尔类型编码为t和nil点数编码为Go言的格式,复数1+2i编码为#C(1.0 2.0)格式。接口编码为类型名和值,例如("[]int" (1 2 3)),但是这个形式可能造成歧reflect.Type.String方法对于不同的型可能返相同的果。
**練習 12.4** 改encode函,以上面的格式化形式出S表式。
**练习 12.4** 改encode函,以上面的格式化形式出S表式。
**練習 12.5** 改encode函用JSON格式代替S表式格式。然使用標準庫提供的json.Unmarshal解碼器來驗證函數是正的。
**练习 12.5** 改encode函用JSON格式代替S表式格式。然使用标准库提供的json.Unmarshal解码器来验证函数是正的。
**練習 12.6** 改encode爲一個優化,忽略是零值象的編碼
**练习 12.6** 改encode为一个优化,忽略是零值象的编码
**練習 12.7** 建一個基於流式的APIS表式的解和json.Decoder(§4.5)函功能似。
**练习 12.7** 建一个基于流式的APIS表式的解和json.Decoder(§4.5)函功能似。