2014-09-27 73 views
0
func Marshal(v interface{}) ([]byte, error) 
func Unmarshal(data []byte, v interface{}) error 

通知元帥接受的接口,並返回一個 []字節作爲輸出,而解組接受[]字節和直接寫入輸出到輸入參數數據爲什麼json.Marshal和json.Unmarshal具有不同的簽名

做什麼設計

聯營問題的區別:

我想使用的輸入參數可以保存在內存中複製一次(樂趣ction return需要一個副本),golang中的每個賦值都是一個副本操作,所以看起來Unmarshal可以保存副本,但不是Marshal。

所以我很困惑...

+1

沒有去語言專家。但是,如果你將一些數據序列化(Marshall)成一個字節數組,大多數情況下事先並不知道字節數組的大小。因此,他們返回一個字節數組,其大小正確,而不是在函數參數列表中設計一個可以處理數組大小參數的接口。相反,Unmarshall(反序列化)需要一個字節數組(來自某個傳輸層),因此不存在這個問題。 – BitTickler 2014-09-27 02:04:48

+0

@ user2225104謝謝 – Nowhy 2014-09-27 02:59:22

+0

Unmarshal寫入'v',而不是'data'。 'Marshal'可以接受一個輸入字節片並返回一個(可能是重新分配的)帶有JSON的字節片,如果先前alloc'd數組足夠大,可能會避免分配。討論過的人們使得Marshaler界面能夠做到這一點,但認爲它的好處並不值得。請注意,無論如何不會有JSON字節的副本; [切片(和字符串,和其他一些東西)包含指針](http://stackoverflow.com/questions/23542989/pointers-vs-values-in-parameters-and-return-values/23551970#23551970);複製它們不會複製內容。 – twotwotwo 2014-09-27 03:42:08

回答

2

對稱對的潛在功能是:

func Marshal(v interface{}) ([]byte, error)   // 1 
func Unmarshal(data []byte) (interface{}, error) // 2 

func Marshal(v interface{}, data *[]byte) error  // 3 
func Unmarshal(data []byte, v interface{}) error // 4 

功能#3,#4看起來不夠對稱,因爲data參數#3是一個指針類型和v參數#4不宣成爲一個指針類型。它們實際上是對稱的,因爲傳遞給#4的v參數的實際值必須是指針。如果函數不是指針,該函數將返回一個錯誤。

功能#2不可行,因爲該功能無法訪問應用程序的結果類型。如果函數不知道類型,則函數無法將JSON解組爲類型。此外,應用程序需要鍵入斷言結果才能使用它。標準庫儘可能避免類型斷言。

功能#3不是慣用的。 GO中很少使用指向切片的指針。我不記得在標準庫中使用任何標準庫,但我確信有人會在這裏留下評論,如果有的話。

我們留下的不對稱對#1和#4:

func Marshal(v interface{}) ([]byte, error)   // 1 
func Unmarshal(data []byte, interface{}) error  // 4 
+0

對於編組接口(不是這些函數,但方法類似於精神),安德魯Gerrand的Go團隊[浮動'追加'式簽名](http://grokbase.com/p/gg/golang-dev/137hbjp6qs/go-1-2-encoding-xml-marshaler-and-unmarshaler)(拿一個' [] byte'並返回另一個,可能是重新分配的,[[] byte')。它被拒絕了,我認爲是因爲他們認爲它會讓所有用戶的API複雜化,這是很多人不會在意的一個小的速度提升。 – twotwotwo 2014-09-27 06:43:10

+0

另一個不一定更快的選擇是將作者接口而不是目標字節數組直接傳遞給Marshall函數。這可以根據作者的工作方式進行優化。在分層通信中,標題被預先添加或者消息正在跨越各個層組成是不常見的。但在桌面上,它應該不是很重要,而最有可能在小型嵌入式系統上使用,否則不會使用語言。 – BitTickler 2014-10-01 16:12:55

0

通過具有Marshal返回一個字節數組,你可以很容易地傳遞給函數一樣bufio.Writer.Write()這需要一個字節數組作爲參數。當您編寫提供JSON的Web服務時,您可能會遇到其中之一。

如果您使用的是Unmarshal,那麼您可能正在閱讀JSON。通過讓Unmarshal採用與Marshal返回相同的第一個參數,您可以獲得任何已由Marshal輸出的JSON,並將其直接傳遞給Unmarshal

相關問題