2014-09-27 74 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

相关问题