在Golang中序列化JSON字符串的教程

简介: 在Golang中,使用`json.Marshal()`可将数据结构序列化为JSON格式。若直接对JSON字符串进行序列化,会因转义字符导致错误。解决方案包括使用`[]byte`或`json.RawMessage()`来避免双引号被转义,从而正确实现JSON的序列化与反序列化。

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字符串:

  1. 使用[]byte()
  2. 使用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字符串,这是一个完美的方法。


转载来源:https://juejin.cn/post/7112985563296169991

相关文章
|
13天前
|
XML JSON 编解码
从JSON到Protobuf,深入序列化方案的选型与原理
序列化是数据跨边界传输的“翻译官”,将结构化数据转为二进制流。JSON可读性强但冗余大,Protobuf高效紧凑、性能优越,成主流选择。不同场景需权衡标准化与定制优化,选最合适方案。
146 3
|
4月前
|
XML JSON Java
go语言之JSON序列化
本文介绍了Go语言中的JSON序列化与反序列化,其操作与Java类似。需要注意的是,由于Go语言的包管理机制,变量和引入包的首字母需大写,以便其他包引用。示例代码展示了如何将`Student`结构体进行JSON序列化(返回字节数组,需转为字符串)及反序列化。此外,文章还说明了通过tag(如`json`和`xml`)指定序列化变量的重要性,以避免因包间访问限制导致反序列化失败或值为null的问题。
|
5月前
|
JSON JavaScript 前端开发
Go语言JSON 序列化与反序列化 -《Go语言实战指南》
本文介绍了 Go 语言中使用 `encoding/json` 包实现 JSON 与数据结构之间的转换。内容涵盖序列化(`Marshal`)和反序列化(`Unmarshal`),包括基本示例、结构体字段标签的使用、控制字段行为的标签(如 `omitempty` 和 `-`)、处理 `map` 和切片、嵌套结构体序列化、反序列化未知结构(使用 `map[string]interface{}`)以及 JSON 数组的解析。最后通过表格总结了序列化与反序列化的方法及类型要求,帮助开发者快速掌握 JSON 数据处理技巧。
|
8月前
|
JSON JavaScript 前端开发
处理从API返回的JSON数据时返回Unicode编码字符串怎么处理
在处理API返回的JSON数据时,遇到类似`\u7f51\u7edc\u8fde\u63a5\u9519\u8bef`的Unicode编码字符串,可使用JavaScript内置方法转换为可读文字。主要方法包括:1. 使用`JSON.parse`自动解析;2. 使用`decodeURIComponent`和`escape`组合解码;3. 在API调用中直接处理响应数据。这些方法能有效处理多语言内容,确保正确显示非ASCII字符。
|
11月前
|
JSON JavaScript 前端开发
Go语言中json序列化的一个小坑,建议多留意一下
在Go语言开发中,JSON因其简洁和广泛的兼容性而常用于数据交换,但其在处理数字类型时存在精度问题。本文探讨了JSON序列化的一些局限性,并介绍了两种替代方案:Go特有的gob二进制协议,以及msgpack,两者都能有效解决类型保持和性能优化的问题。
262 7
|
11月前
|
JSON 前端开发 JavaScript
聊聊 Go 语言中的 JSON 序列化与 js 前端交互类型失真问题
在Web开发中,后端与前端的数据交换常使用JSON格式,但JavaScript的数字类型仅能安全处理-2^53到2^53间的整数,超出此范围会导致精度丢失。本文通过Go语言的`encoding/json`包,介绍如何通过将大整数以字符串形式序列化和反序列化,有效解决这一问题,确保前后端数据交换的准确性。
259 4
|
11月前
|
JSON JavaScript Java
对比JSON和Hessian2的序列化格式
通过以上对比分析,希望能够帮助开发者在不同场景下选择最适合的序列化格式,提高系统的整体性能和可维护性。
311 3
|
11月前
|
JSON 数据格式 索引
Python中序列化/反序列化JSON格式的数据
【11月更文挑战第4天】本文介绍了 Python 中使用 `json` 模块进行序列化和反序列化的操作。序列化是指将 Python 对象(如字典、列表)转换为 JSON 字符串,主要使用 `json.dumps` 方法。示例包括基本的字典和列表序列化,以及自定义类的序列化。反序列化则是将 JSON 字符串转换回 Python 对象,使用 `json.loads` 方法。文中还提供了具体的代码示例,展示了如何处理不同类型的 Python 对象。
345 1
|
11月前
|
JSON JavaScript 前端开发
|
XML 存储 JSON
c#XML、JSON的序列化和反序列化,看完你就懂了
c#XML、JSON的序列化和反序列化,看完你就懂了
445 0