为什么在解组JSON时字符串和[]字节的处理方式不同?

时间:2015-01-31 02:51:38

标签: json go unmarshalling

通过阅读文档,我的理解是string本质上是一个不可变的[]byte,并且可以轻松地在两者之间进行转换。

然而,当从JSON解组时,这似乎并非如此。参加以下示例程序:

package main

import (
    "encoding/json"
    "fmt"
)

type STHRaw struct {
    Hash []byte `json:"hash"`
}

type STHString struct {
    Hash string `json:"hash"`
}

func main() {
    bytes := []byte(`{"hash": "nuyHN9wx4lZL2L3Ir3dhZpmggTQEIHEZcC3DUNCtQsk="}`)

    stringHead := new(STHString)
    if err := json.Unmarshal(bytes, &stringHead); err != nil {
        return
    }

    rawHead := new(STHRaw)
    if err := json.Unmarshal(bytes, &rawHead); err != nil {
        return
    }

    fmt.Printf("String:\t\t%x\n", stringHead.Hash)
    fmt.Printf("Raw:\t\t%x\n", rawHead.Hash)
    fmt.Printf("Raw to string:\t%x\n", string(rawHead.Hash[:]))
}

这给出了以下输出:

String:         6e7579484e397778346c5a4c324c3349723364685a706d67675451454948455a63433344554e437451736b3d
Raw:            9eec8737dc31e2564bd8bdc8af77616699a0813404207119702dc350d0ad42c9
Raw to string:  9eec8737dc31e2564bd8bdc8af77616699a0813404207119702dc350d0ad42c9 

相反,我希望每次都能获得相同的值。

有什么区别?

1 个答案:

答案 0 :(得分:4)

encoding/json包的设计者决定应用程序必须在string值中提供有效的UTF-8文本,并且应用程序可以将任意字节序列放在[]byte值中。包base64对[]byte值进行编码,以确保生成的字符串是有效的UTF-8。

Marshal function documentation中描述了[]byte值的编码。

这一决定并非由Go语言的设计决定。 string类型可以包含任意字节序列。 []byte类型可以包含有效的UTF-8文本。

设计人员可以在字段标记中使用标记来指示应编码string[]byte值以及要使用的编码器,但这不是他们所做的。