Go 编程 | 连载 29 - Go 与 JSON

简介: Go 编程 | 连载 29 - Go 与 JSON

二、Go 与 JSON 的格式映射

在序列化和反序列化时需考虑 JavaScript 和 Go 表示数据类型的方式,Go 是静态强类型语言,JavaScript 是动态弱类型语言。

Go 中声明变量是需要声明数据类型的,即使不声明数据类型 Go 也会在编译器自动判断数据类型,而 JavaScript 则是在运行时才会判断数据类型。 JSON 的数据格式与 JavaScript 相同,JSON 可使用的格式有如下几种:

  • Boolean
  • Number
  • String
  • Array
  • Object
  • Null

但是这些数据类型不会自动映射到 Go 中的数据类型,需要通过 encoding/json 包执行显示的类型转换,JSON 和 Go 中数据类型之间的对应关系如下:

JSON 类型 Go 类型
String string
Boolean bool
Number float64
Array []interface{}
Object map[string]interface{}
Null nil
package main
import (
   "encoding/json"
   "fmt"
   "log"
)
//noinspection ALL
func main() {
   jsonString := `{"name": "stark", "is_vip": "true"}`
   u := User{}
   err := json.Unmarshal([]byte(jsonString), &u)
   if err != nil {
      log.Fatal(err)
   }
   fmt.Println(u)
}
type User struct {
   Name string `json:"name"`
   IsVip bool `json:"is_vip"`
}
复制代码

执行上述代码,输出结果如下:

2022/09/01 11:41:45 json: cannot unmarshal string into Go struct field User.is_vip of type bool
复制代码

上述代码反序列化过程中, Go 会将字符串格式的 true 转换为 bool 类型的 true,因此转换失败导致程序停止。

在进行反序列化时要注意 JavaScript 和 Go 之间的类型对应关系,如果转换时类型不对应则会导致错误。

三、处理 HTTP 收到的 JSON 格式数据

在 Go 语言中通过 HTTP 请求收到的 JSON 数据是以流的形式接收的,既不是字符串也不是字节切片,因此需要通过 encoding/json 标准库中的另一个函数 New.Decoder 来进行解码。

我们通过 Gin 框架快速创建一个返回 JSON 格式的 API,使用 net/http 调用这个 API 获取到 JSON 数据,然后将 JSON 数据转换成结构体实例化对象。

首先新建一个 gin-quickstart 项目,然后通过命令行安装 Gin 框架

go get -u github.com/gin-gonic/gin
复制代码

新建 main.go 文件,添加如下代码:

package main
// 导入 gin 依赖
//noinspection ALL
import (
   "github.com/gin-gonic/gin"
   "net/http"
)
//noinspection ALL
func main(){
   // 创建路由 engine
   r := gin.Default()
   // 创建路由,绑定 handler 函数
   r.GET("/json", ResponseJsonHandler)
   // 启动,绑定端口
   r.Run(":8080")
}
func ResponseJsonHandler (c *gin.Context) {
   d := Data{
      Msg:  "你好 JSON",
      Code: 20000,
   }
   c.JSON(http.StatusOK, d)
}
type Data struct {
   Msg string `json:"msg"`
   Code int `json:"code"`
}
复制代码

运行 main.go 文件,此时我们就已经搭建了一个 HTTP 服务器,在浏览器中访问 http://localhost:8080/json 可以获取如下响应

image.png

接着我们另外一个项目中新建一个 Go 文件,输入如下代码:

package main
//noinspection ALL
import (
   "encoding/json"
   "fmt"
   "log"
   "net/http"
)
//noinspection ALL
func main() {
   data := Data{}
   // 访问 /json API
   res, err := http.Get("http://localhost:8080/json")
   if err != nil {
      log.Fatal(err)
   }
   fmt.Println(res)
   defer res.Body.Close()
   // 处理 JSON 流,将其数据赋值到一个结构体实例化对象 data 上 
   err = json.NewDecoder(res.Body).Decode(&data)
   if err != nil {
      log.Fatal(err)
   }
   fmt.Printf("%+v\n", data)
   fmt.Printf("%T\n", data)
}
type Data struct {
   Msg string `json:"msg"`
   Code int `json:"code"`
}
复制代码

执行上述代码,输出结果如下:

&{200 OK 200 HTTP/1.1 1 1 map[Content-Length:[34] Content-Type:[application/json; charset=utf-8] Date:[Thu, 01 Sep 2022 17:29:25 GMT]] 0xc00015e400 34 [] false false map[] 0xc00017e000 <nil>}
{Msg:你好 JSON Code:20000}
main.Data


相关文章
|
8月前
|
设计模式 缓存 算法
Go如何进行高质量编程与性能调优实践
本文介绍了Go语言高质量编程与性能调优的实践方法。高质量编程包括良好的编码习惯(如清晰注释、命名规范)、代码风格与设计(如MVC模式)、简洁明了的代码原则,以及单元测试与代码重构的重要性。性能调优方面,涵盖算法优化、数据结构选择、I/O优化、内存管理、并行与并发处理优化及代码层面的改进。通过这些方法,可有效提升代码质量和系统性能。
182 13
|
8月前
|
分布式计算 Go C++
初探Go语言RPC编程手法
总的来说,Go语言的RPC编程是一种强大的工具,让分布式计算变得简单如同本地计算。如果你还没有试过,不妨挑战一下这个新的编程领域,你可能会发现新的世界。
213 10
|
8月前
|
JSON JavaScript 前端开发
Go语言JSON 序列化与反序列化 -《Go语言实战指南》
本文介绍了 Go 语言中使用 `encoding/json` 包实现 JSON 与数据结构之间的转换。内容涵盖序列化(`Marshal`)和反序列化(`Unmarshal`),包括基本示例、结构体字段标签的使用、控制字段行为的标签(如 `omitempty` 和 `-`)、处理 `map` 和切片、嵌套结构体序列化、反序列化未知结构(使用 `map[string]interface{}`)以及 JSON 数组的解析。最后通过表格总结了序列化与反序列化的方法及类型要求,帮助开发者快速掌握 JSON 数据处理技巧。
|
JSON JavaScript 前端开发
Go语言中json序列化的一个小坑,建议多留意一下
在Go语言开发中,JSON因其简洁和广泛的兼容性而常用于数据交换,但其在处理数字类型时存在精度问题。本文探讨了JSON序列化的一些局限性,并介绍了两种替代方案:Go特有的gob二进制协议,以及msgpack,两者都能有效解决类型保持和性能优化的问题。
428 7
|
JSON 前端开发 JavaScript
聊聊 Go 语言中的 JSON 序列化与 js 前端交互类型失真问题
在Web开发中,后端与前端的数据交换常使用JSON格式,但JavaScript的数字类型仅能安全处理-2^53到2^53间的整数,超出此范围会导致精度丢失。本文通过Go语言的`encoding/json`包,介绍如何通过将大整数以字符串形式序列化和反序列化,有效解决这一问题,确保前后端数据交换的准确性。
375 4
|
数据采集 监控 Java
go语言编程学习
【11月更文挑战第3天】
247 7
|
数据库连接 Go 数据库
Go语言中的错误注入与防御编程。错误注入通过模拟网络故障、数据库错误等,测试系统稳定性
本文探讨了Go语言中的错误注入与防御编程。错误注入通过模拟网络故障、数据库错误等,测试系统稳定性;防御编程则强调在编码时考虑各种错误情况,确保程序健壮性。文章详细介绍了这两种技术在Go语言中的实现方法及其重要性,旨在提升软件质量和可靠性。
228 1
|
Unix Linux Go
go进阶编程:Golang中的文件与文件夹操作指南
本文详细介绍了Golang中文件与文件夹的基本操作,包括读取、写入、创建、删除和遍历等。通过示例代码展示了如何使用`os`和`io/ioutil`包进行文件操作,并强调了错误处理、权限控制和路径问题的重要性。适合初学者和有经验的开发者参考。
246 4
|
Java 大数据 Go
Go语言:高效并发的编程新星
【10月更文挑战第21】Go语言:高效并发的编程新星
472 7
|
Go 数据处理 调度
Go语言中的并发模型:解锁高效并行编程的秘诀
本文将探讨Go语言中独特的并发模型及其在现代软件开发中的应用。通过深入分析 Goroutines 和 Channels,我们将揭示这一模型如何简化并行编程,提升应用性能,并改变开发者处理并发任务的方式。不同于传统多线程编程,Go的并发方法以其简洁性和高效性脱颖而出,为开发者提供了一种全新的编程范式。