为什么json.Marshal和json.Unmarshal有不同的签名

时间:2014-09-27 01:52:51

标签: go

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

注意Marshal接受一个接口而返回一个[]字节作为输出,而Unmarshal接受一个[]字节并将输出直接写入输入参数数据

什么使设计有所不同

一个助理问题:

我认为使用输入参数可以保存内存中的副本一次(函数返回需要一个副本),golang中的每个赋值都是一个副本操作,所以它看起来像Unmarshal可以保存副本,但Marshal没有。

所以我很困惑......

2 个答案:

答案 0 :(得分: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可能看起来不对称,因为#3的data参数是指针类型,而#4的v参数未声明为指针类型。它们实际上是对称的,因为传递给#4的v参数的实际值必须是指针。如果函数不是指针,则该函数返回错误。

函数#2不可行,因为该函数无法访问应用程序的结果类型。如果函数不知道类型,则函数无法将JSON解组为类型。此外,应用程序将需要键入断言结果以使用它。标准库尽可能避免类型断言。

功能#3不是惯用的。切片中的指针很少用于Go。我不记得在标准库中使用任何标识库,但我相信如果有标记库,有人会在这里发表评论。

我们留下了#1和#4的不对称对:

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

答案 1 :(得分:0)

通过让Marshal返回一个字节数组,您可以轻松地将其传递给像bufio.Writer.Write()这样的函数,它将一个字节数组作为参数。当您编写提供JSON服务的Web服务时,您可能会拥有其中一个。

如果您使用的是Unmarshal,那么您可能正在阅读JSON。通过让Unmarshal使用与Marshal返回相同的第一个参数,您可以获取Marshal输出的任何JSON,并将其直接传递给Unmarshal