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


相关文章
|
15天前
|
数据采集 监控 Java
go语言编程学习
【11月更文挑战第3天】
31 7
|
21天前
|
Unix Linux Go
go进阶编程:Golang中的文件与文件夹操作指南
本文详细介绍了Golang中文件与文件夹的基本操作,包括读取、写入、创建、删除和遍历等。通过示例代码展示了如何使用`os`和`io/ioutil`包进行文件操作,并强调了错误处理、权限控制和路径问题的重要性。适合初学者和有经验的开发者参考。
|
29天前
|
Java 大数据 Go
Go语言:高效并发的编程新星
【10月更文挑战第21】Go语言:高效并发的编程新星
49 7
|
1月前
|
Go 数据处理 调度
Go语言中的并发模型:解锁高效并行编程的秘诀
本文将探讨Go语言中独特的并发模型及其在现代软件开发中的应用。通过深入分析 Goroutines 和 Channels,我们将揭示这一模型如何简化并行编程,提升应用性能,并改变开发者处理并发任务的方式。不同于传统多线程编程,Go的并发方法以其简洁性和高效性脱颖而出,为开发者提供了一种全新的编程范式。
|
1月前
|
JSON 数据格式 Python
Python编程:利用JSON模块编程验证用户
Python编程:利用JSON模块编程验证用户
|
1月前
|
并行计算 算法 搜索推荐
探索Go语言的高并发编程与性能优化
【10月更文挑战第10天】探索Go语言的高并发编程与性能优化
|
2月前
|
存储 缓存 Go
go语言编程系列(五)
go语言编程系列(五)
|
2月前
|
搜索推荐 Java 编译器
go语言编程系列(四)
go语言编程系列(四)
|
2月前
|
存储 JSON 安全
go语言编程系列(七)
go语言编程系列(七)
|
2月前
|
存储 安全 编译器
go语言编程系列(六)
go语言编程系列(六)
下一篇
无影云桌面