Fixes #198
This commit is contained in:
chai2010
2016-01-18 11:22:04 +08:00
parent 884ada9cd0
commit 9666211cd7
71 changed files with 107 additions and 105 deletions

View File

@@ -10,7 +10,7 @@ err := json.Unmarshal(data, &movie)
Unmarshal函數使用了反射機製類脩改movie變量的每個成員根據輸入的內容爲Movie成員創建對應的map、結構體和slice。
現在讓我們爲S表達式編碼實現一個簡易的Unmarshal類似於前面的json.Unmarshal標準庫函數對應我們之前實現的sexpr.Marshal函數的逆操作。我們必提醒一下一個健壯的和通用的實現通常需要比例子更多的代碼爲了便於演示我們采用了精簡的實現。我們隻支持S表達式有限的子集同時處理錯誤的方式也比較粗暴代碼的目的是爲了演示反射的用法而不是構造一個實用的S表達式的解碼器。
現在讓我們爲S表達式編碼實現一個簡易的Unmarshal類似於前面的json.Unmarshal標準庫函數對應我們之前實現的sexpr.Marshal函數的逆操作。我們必提醒一下一個健壯的和通用的實現通常需要比例子更多的代碼爲了便於演示我們采用了精簡的實現。我們隻支持S表達式有限的子集同時處理錯誤的方式也比較粗暴代碼的目的是爲了演示反射的用法而不是構造一個實用的S表達式的解碼器。
詞法分析器lexer使用了標準庫中的text/scanner包將輸入流的字節數據解析爲一個個類似註釋、標識符、字符串面值和數字面值之類的標記。輸入掃描器scanner的Scan方法將提前掃描和返迴下一個記號對於rune類型。大多數記號比如“(”對應一個單一rune可表示的Unicode字符但是text/scanner也可以用小的負數表示記號標識符、字符串等由多個字符組成的記號。調用Scan方法將返迴這些記號的類型接着調用TokenText方法將返迴記號對應的文本內容。
@@ -74,7 +74,7 @@ func read(lex *lexer, v reflect.Value) {
最有趣的部分是遞歸。最簡單的是對數組類型的處理。直到遇到“)”結束標記我們使用Index函數來獲取數組每個元素的地址然後遞歸調用read函數處理。和其它錯誤類似如果輸入數據導致解碼器的引用超出了數組的范圍解碼器將拋出panic異常。slice也采用類似方法解析不同的是我們將爲每個元素創建新的變量然後將元素添加到slice的末尾。
在循環處理結構體和map每個元素時必解碼一個(key value)格式的對應子列表。對於結構體key部分對於成員的名字。和數組類似我們使用FieldByName找到結構體對應成員的變量然後遞歸調用read函數處理。對於mapkey可能是任意類型對元素的處理方式和slice類似我們創建一個新的變量然後遞歸填充它最後將新解析到的key/value對添加到map。
在循環處理結構體和map每個元素時必解碼一個(key value)格式的對應子列表。對於結構體key部分對於成員的名字。和數組類似我們使用FieldByName找到結構體對應成員的變量然後遞歸調用read函數處理。對於mapkey可能是任意類型對元素的處理方式和slice類似我們創建一個新的變量然後遞歸填充它最後將新解析到的key/value對添加到map。
```Go
func readList(lex *lexer, v reflect.Value) {