Marshal递归地遍历接口的值。如果遇到的值实现了Marshaler接口,并且不是一个nil指针,Marshal会调用它的MarshalJSON方法来产生JSON。
Golang序列化JSON字符串
要在Golang中序列化 JSON 字符串,请使用 json.Marshal()函数。Golang json.Marshal()函数返回接口的JSON编码。
请看下面的代码。
go 体验AI代码助手 代码解读复制代码// hello.go
package main
import (
"encoding/json"
"fmt"
)
// Tesla struct
type Tesla struct {
ProductName string `json:"productName"`
ProductPrice string `json:"productPrice"`
}
func main() {
in := `{"productName":"CyberTruck","productPrice": 39900}`
bytes, err := json.Marshal(in)
if err != nil {
panic(err)
}
var t Tesla
err = json.Unmarshal(bytes, &t)
if err != nil {
panic(err)
}
fmt.Printf("%+v", t)
}
输出
go 体验AI代码助手 代码解读复制代码go run hello.go
panic: json: cannot unmarshal string into Go value of type main.Tesla
goroutine 1 [running]:
main.main()
/Users/krunal/Desktop/code/go/src/hello/hello.go:25 +0x1d8
exit status 2
所以,它会惊慌失措并返回一个错误。
现在,写下下面的代码,看看到底发生了什么。
go 体验AI代码助手 代码解读复制代码// hello.go
package main
import (
"encoding/json"
"fmt"
)
// Tesla struct
type Tesla struct {
ProductName string `json:"productName"`
ProductPrice string `json:"productPrice"`
}
func main() {
in := `{"productName":"CyberTruck","productPrice": 39900}`
bytes, err := json.Marshal(in)
if err != nil {
panic(err)
}
fmt.Println(string(bytes))
}
输出
swift 体验AI代码助手 代码解读复制代码go run hello.go
"{\"productName\":\"CyberTruck\",\"productPrice\": 39900}"
当我们将JSON字符串转换为通常的字符串时,它确实转义了双引号,这就是为什么它返回一个错误。
那么,你如何跳过转义?
好吧,我们有两个解决方案来正确序列化JSON字符串:
使用[]byte()
使用json.RawMessage()
Golang []byte
Golang byte是uint8的别名,在所有方面都等同于uint8。按照惯例,字节是用来区分字节值和8位无符号整数值的。
请看下面的代码。
go 体验AI代码助手 代码解读复制代码// hello.go
package main
import (
"encoding/json"
"fmt"
)
// Tesla struct
type Tesla struct {
ProductName string `json:"productName"`
ProductPrice string `json:"productPrice"`
}
func main() {
data := `{"productName":"CyberTruck","productPrice":"39900"}`
bytes := []byte(data)
var t Tesla
err := json.Unmarshal(bytes, &t)
if err != nil {
panic(err)
}
fmt.Printf("%+v \n", t)
fmt.Println(string(bytes))
}
输出
go 体验AI代码助手 代码解读复制代码go run hello.go
{ProductName:CyberTruck ProductPrice:39900}
{"productName":"CyberTruck","productPrice":"39900"}
在上面的程序中,我们已经将json转换为一个字节数组。所以它防止了双引号的转义,然后我们使用了json.Unmarshal()函数。
Golang json.RawMessage()
Golang json 包 包含了一个解决这个问题的方法。Golang json有RawMessage类型,它的Marshalls和Unmarshal不需要转义。要序列化JSON字符串,你需要在之后将其反序列化为一个结构,用json.RawMessage()来做。
请看下面的代码示例。
go 体验AI代码助手 代码解读复制代码// hello.go
package main
import (
"encoding/json"
"fmt"
)
// Tesla struct
type Tesla struct {
ProductName string `json:"productName"`
ProductPrice string `json:"productPrice"`
}
func main() {
data := `{"productName":"CyberTruck","productPrice":"39900"}`
rawData := json.RawMessage(data)
bytes, err := rawData.MarshalJSON()
if err != nil {
panic(err)
}
var t Tesla
err = json.Unmarshal(bytes, &t)
if err != nil {
panic(err)
}
fmt.Printf("%+v \n", t)
fmt.Println(string(bytes))
}
输出
go 体验AI代码助手 代码解读复制代码go run hello.go
{ProductName:CyberTruck ProductPrice:39900}
{"productName":"CyberTruck","productPrice":"39900"}
它返回相同的输出。
RawMessage是一个原始编码的JSON值。它实现了Marshaler和Unmarshaler,可以用来延迟JSON解码或预先计算JSON编码。MarshalJSON返回RawMessage作为RawMessage的JSON编码。
序列化结构
串行化的结构与我们的JSON字符串相同。因此, 确保JSON字符串与Tesla结构相匹配。
请看下面的代码。
go 体验AI代码助手 代码解读复制代码// hello.go
package main
import (
"encoding/json"
"fmt"
)
// Tesla struct
type Tesla struct {
ProductName string `json:"productName"`
ProductPrice string `json:"productPrice"`
}
func main() {
bytes, err := json.Marshal(Tesla{
ProductName: "CyberTruck",
ProductPrice: "39900",
})
if err != nil {
panic(err)
}
fmt.Println(string(bytes))
}
输出
go 体验AI代码助手 代码解读复制代码go run hello.go
{"productName":"CyberTruck","productPrice":"39900"}
结论
序列化的结构在json.Marshal()函数中运行良好,但直接序列化的JSON字符串不支持Marshal(),因为它转义了双引号。所以为了避免这种情况,我们可以使用[]byte或 json.RawMessage()函数。
如果你想在Golang中手动序列化JSON字符串,这是一个完美的方法。