在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

相关文章
|
8月前
|
XML JSON 编解码
重新认识 Golang 中的 json 编解码
欢迎访问[莹的网络日志](https://lifukun.com),分享技术探索与思考。本文深入解析Go中json编解码特性,涵盖字段映射、omitempty行为、性能对比、自定义编解码及json/v2新特性,助你真正掌握json使用细节。
|
JSON JavaScript 前端开发
处理从API返回的JSON数据时返回Unicode编码字符串怎么处理
在处理API返回的JSON数据时,遇到类似`\u7f51\u7edc\u8fde\u63a5\u9519\u8bef`的Unicode编码字符串,可使用JavaScript内置方法转换为可读文字。主要方法包括:1. 使用`JSON.parse`自动解析;2. 使用`decodeURIComponent`和`escape`组合解码;3. 在API调用中直接处理响应数据。这些方法能有效处理多语言内容,确保正确显示非ASCII字符。
|
JSON 前端开发 JavaScript
json字符串如何转为list对象?
json字符串如何转为list对象?
2297 7
|
JSON 数据格式 Python
6-1|Python如何将json转化为字符串写到文件内 还保留json格式
6-1|Python如何将json转化为字符串写到文件内 还保留json格式
|
JSON API 数据格式
4. JSON字符串是如何被解析的?JsonParser了解一下(下)
4. JSON字符串是如何被解析的?JsonParser了解一下(下)
|
JSON JavaScript 前端开发
4. JSON字符串是如何被解析的?JsonParser了解一下(中)
4. JSON字符串是如何被解析的?JsonParser了解一下(中)
4. JSON字符串是如何被解析的?JsonParser了解一下(中)
|
JSON Java fastjson
|
SQL JSON 监控
实时计算 Flink版产品使用合集之直接将 JSON 字符串解析为数组的内置函数如何解决
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
JSON Java 测试技术
4. JSON字符串是如何被解析的?JsonParser了解一下(上)
4. JSON字符串是如何被解析的?JsonParser了解一下(上)
4. JSON字符串是如何被解析的?JsonParser了解一下(上)
|
存储 数据采集 JSON
如何不写一行代码把 Mysql json 字符串解析为 Elasticsearch 的独立字段
1、事出有因 实战问题:有数百万数据需要导入 Elasticsearch 做性能对比测试,但当前数据存储在 Mysql 中,且核心字段以 Json 字符串形式存储。Mysql 存储如下所示:
如何不写一行代码把 Mysql json 字符串解析为 Elasticsearch 的独立字段

推荐镜像

更多