教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 如何在Golang中正确序列化JSON字符串

如何在Golang中正确序列化JSON字符串

发布时间:2023-03-01   编辑:jiaochengji.com
教程集为您提供如何在Golang中正确序列化JSON字符串等资源,欢迎您收藏本站,我们将为您提供最新的如何在Golang中正确序列化JSON字符串资源

1.Json.Marshal会有什么问题?

下边示例是将json序列化成bytes,然后把bytes反序列化到匹配的结构体。

package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	FirstName string `json:"firstName"`
	LastName  string `json:"lastName"`
}

func main() {
	in := `{"firstName":"John","lastName":"Dow"}`

	bytes, err := json.Marshal(in)
	if err != nil {
		panic(err)
	}

	var p Person
	err = json.Unmarshal(bytes, &p)
	if err != nil {
		panic(err)
	}

	fmt.Printf("% v", p)
}

运行程序发现,程序panic了。

panic: json: cannot unmarshal string into Go value of type main.Person

goroutine 1 [running]:
main.main()
	/tmp/sandbox071126523/prog.go:24  0x1e9

这不是我们想要的,接下来我们确认下json字符串是否跟Person结构体相匹配。

package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	FirstName string `json:"firstName"`
	LastName  string `json:"lastName"`
}

func main() {
	bytes, err := json.Marshal(Person{
		FirstName: "John",
		LastName:  "Dow",
	})
	if err != nil {
		panic(err)
	}

	fmt.Println(string(bytes))
}

输出的结果如下:

{"firstName":"John","lastName":"Dow"}

序列化后的结构体,跟我们的json字符串是一样的。

2.原因是什么?

我们比较一下序列化json字符串以及结构体序列化的结果。

package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	FirstName string `json:"firstName"`
	LastName  string `json:"lastName"`
}

func main() {
	bytes, err := json.Marshal(Person{
		FirstName: "John",
		LastName:  "Dow",
	})
	if err != nil {
		panic(err)
	}

	fmt.Println(string(bytes))

	in := `{"firstName":"John","lastName":"Dow"}`

	bytes, err = json.Marshal(in)
	if err != nil {
		panic(err)
	}

	fmt.Println(string(bytes))
}

输出结果如下:

{"firstName":"John","lastName":"Dow"}
"{\"firstName\":\"John\",\"lastName\":\"Dow\"}"

你能看到转义的双引号么?这是问题的症结所在,json.Marshal在对字符串进行序列化的时候,会对字符串进行转义

3.如何避免被转义

json包对这个问题有一个解决方案,它有一个RawMessage类型,在序列化及反序列化时不会对字符串进行转义。
所以,如果你需要序列化一个json字符串,后续再反序列化到结构体里,可以用json.RawMessage来实现。

package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	FirstName string `json:"firstName"`
	LastName  string `json:"lastName"`
}

func main() {
	in := `{"firstName":"John","lastName":"Dow"}`

	rawIn := json.RawMessage(in)
	bytes, err := rawIn.MarshalJSON()
	if err != nil {
		panic(err)
	}

	var p Person
	err = json.Unmarshal(bytes, &p)
	if err != nil {
		panic(err)
	}

	fmt.Printf("% v", p)
}

输出结果如下:

{FirstName:John LastName:Dow}

是正确的结果。

4.有没有更简单的方式

有的,json.RawMessage实际上是[]byte类型的,所以你需要做的就是把字符串转换成[]byte类型。

package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	FirstName string `json:"firstName"`
	LastName  string `json:"lastName"`
}

func main() {
	in := `{"firstName":"John","lastName":"Dow"}`
	bytes := []byte(in)

	var p Person
	err := json.Unmarshal(bytes, &p)
	if err != nil {
		panic(err)
	}

	fmt.Printf("% v", p)
}

输出结果是一样的:

{FirstName:John LastName:Dow}

参考:
How To Correctly Serialize JSON String In Golang

到此这篇关于“如何在Golang中正确序列化JSON字符串”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
golang结构体tag的使用
MySQL 5.7的JSON数据类型详解介绍
Go 学习笔记 09 | Golang 结构体与 JSON 互相转换
想系统学习GO语言(Golang
JSON在PHP中的应用
golang 结构体标签_如何在Go中使用结构标签
jQuery结合Json提交数据到Webservice,并接收从Webservice返回的Json数据
js读取并解析JSON类型数据
php正则表达式完全教程六
php正则表达式完全教程(六)

[关闭]
~ ~