详解Go语言中结构体与JSON间的转换

 更新时间:2022年12月13日 14:07:26   作者:陈明勇  
这篇文章主要为大家详细介绍了Go语言中结构体与JSON间的转换,文中的示例代码讲解详细,对学习Go语言有一定的帮助,需要的可以参考一下

前言

在日常开发中,我们往往会将 JSON 解析成对应的结构体,反之也会将结构体转成 JSON。接下来本文会通过 JSON 包的两个函数,来介绍 JSON 与结构体之间的转换。

结构体转 JSON

Marshal(v any) ([]byte, error):将 v 转成 JSON 数据,以 []byte 的形式返回。

import (
    "encoding/json"
    "fmt"
)

type User struct {
    Name           string
    Age            int
    Height         float64
    Weight         *float64
    Child          bool
    marriageStatus string
}

func main() {
    weight := 120.5
    user := User{
        Name:           "gopher",
        Age:            18,
        Height:         180.5,
        Weight:         &weight,
        Child:          false,
        marriageStatus: "未婚",
    }
    jsonBytes, err := json.Marshal(user)
    if err != nil {
        fmt.Println("error: ", err)
        return
    }
    fmt.Println(string(jsonBytes)) // {"Name":"gopher","Age":18,"Height":180.5,"Weight":120.5,"Child":false}
}

执行结果:

{"Name":"gopher","Age":18,"Height":180.5,"Weight":120.5,"Child":false}

根据结果可知:

  • 不可导出字段(字段名以小写字母开头),是不能被转成 JSONkey 的,这也符合 Go 的语法规定,以小写字母开头的变量或结构体字段等,不能在包外被访问。
  • 转换后的字段名,与结构体字段的名字一样。
  • 如果字段是指针类型,转换后的值为指针指向的字段值。

如果我们想要指定字段转换之后的命名,或者将一个可导出的字段进行忽略,可以通过给结构体字段打上 JSON 标签的方式实现。

import (
    "encoding/json"
    "fmt"
)

type User struct {
    Name           string   `json:"name"`
    Age            int      `json:"age"`
    Height         float64  `json:"height"`
    Weight         *float64 `json:"weight"`
    Child          bool     `json:"child"`
    MarriageStatus string   `json:"-"`
}

func main() {
    weight := 120.5
    user := User{
        Name:           "gopher",
        Age:            18,
        Height:         180.5,
        Weight:         &weight,
        Child:          false,
        MarriageStatus: "未婚",
    }
    jsonBytes, err := json.Marshal(user)
    if err != nil {
        fmt.Println("error: ", err)
        return
    }
    fmt.Println(string(jsonBytes)) // {"name":"gopher","age":18,"height":180.5,"weight":120.5,"child":false}
}

通过给结构体字段定打上 JSON 标签,可指定转成 JSON 后的字段名,如果 JSON 标签的值为 -,则在转换 JSON 时忽略此字段。

JSON 解析结构体

Unmarshal(data []byte, v any) error:将 JSON 解析成指定的结构体。

import (
    "encoding/json"
    "fmt"
)

type User struct {
    Name           string  `json:"name"`
    Age            int     `json:"age"`
    Height         float64 `json:"height"`
    Child          bool    `json:"-"`
    marriageStatus string
}

func main() {
    userStr := `
    {
      "name": "gopher",
      "age": 18,
      "height": 180.5,
      "child": true,
      "marriageStatus": "未婚"
    }
    `
    user := &User{}
    err := json.Unmarshal([]byte(userStr), &user)
    if err != nil {
        fmt.Println("error: ", err)
        return
    }
    fmt.Printf("%#v", user) // &main.User{Name:"gopher", Age:18, Height:180.5, Child:false, marriageStatus:""}
}

执行结果:

&main.User{Name:"gopher", Age:18, Height:180.5, Child:false, marriageStatus:""}

根据结果可知:

使用Unmarshal函数时,我们需要传入结构体的指针类型,否则结构体字段的值将不会被改变,因为底层是通过指针去修改结构体字段的值。

JSON 解析时,JSONkey 与结构体字段的匹配规则是:

  • 优先查找 JSON 标签值和 key 一样的,找到则将 value 赋值给对应字段。
  • 如果没有 JSON 标签值与 key 相匹配,则根据字段名进行匹配。

可以发现,如果结构体字段是非导出字段或 JSON 标签的值为 -,将不会被匹配到。

小结

本文介绍了 Go 语言里,JSON 与结构体之间的转换。在结构体转 JSON 时,我们可以通过给字段打标签,指定转换后的 key 命名,需要注意的是,如果结构体的字段为非导出字段或字段的 JSON 标签值为 -,在转换 JSON 时,将会被忽略。反之 JSON 解析结构体时也是一样的。

到此这篇关于详解Go语言中结构体与JSON间的转换的文章就介绍到这了,更多相关Go语言结构体 JSON内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • golang 流式读取和发送使用场景示例

    golang 流式读取和发送使用场景示例

    这篇文章主要为大家介绍了golang 流式读取和发送使用场景示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • 详解minio分布式文件存储

    详解minio分布式文件存储

    MinIO 是一款基于 Go 语言的高性能、可扩展、云原生支持、操作简单、开源的分布式对象存储产品,这篇文章主要介绍了minio分布式文件存储,需要的朋友可以参考下
    2023-10-10
  • Go数据库迁移的实现步骤

    Go数据库迁移的实现步骤

    本文主要介绍了Go数据库迁移的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • Go 语言简单实现Vigenere加密算法

    Go 语言简单实现Vigenere加密算法

    这篇文章主要介绍了Go语言简单实现Vigenere加密算法,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下
    2022-09-09
  • 一文详解Go Http Server原理

    一文详解Go Http Server原理

    这篇文章主要为大家介绍了Go Http Server原理示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • go语言通过odbc操作Access数据库的方法

    go语言通过odbc操作Access数据库的方法

    这篇文章主要介绍了go语言通过odbc操作Access数据库的方法,实例分析了Go语言通过odbc连接、查询与关闭access数据库的技巧,需要的朋友可以参考下
    2015-03-03
  • Go语言基础知识点介绍

    Go语言基础知识点介绍

    在本篇文章里小编给大家整理的是一篇关于Go语言基础知识点介绍内容,有兴趣的朋友们可以跟着学习参考下。
    2021-07-07
  • 用gin开发的golang项目三种开发模式方式

    用gin开发的golang项目三种开发模式方式

    这篇文章主要介绍了用gin开发的golang项目三种开发模式方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • Go语言hello world实例

    Go语言hello world实例

    这篇文章主要介绍了Go语言hello world实例,本文先是给出了hello world的代码实例,然后对一些知识点和技巧做了解释,需要的朋友可以参考下
    2014-10-10
  • Golang中的Interface详解

    Golang中的Interface详解

    本文详细讲解了Golang中的Interface,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07

最新评论