Go语言的数据结构转JSON

目录
  • 结构体转为 JSON 格式
  • 接口转为 JSON 格式
  • Marshal() 函数的原型
  • 总结

在日常工作中,除了需要从 JSON 转化为 Go 的数据结构。但往往相反的情况是:我们需要将数据以 JSON 字符串的形式发送到 Web 服务器。今天我们将学会如何从一个结构化数据编码为 JSON 。

Json(Javascript Object Nanotation)是一种数据交换格式,常用于前后端数据传输。任意一端将数据转换成json 字符串,另一端再将该字符串解析成相应的数据结构,如string类型,strcut对象等。

结构体转为 JSON 格式

比如,我们有如下的结构体:

type Student struct {
    Name string
    Age int
    Address Address
}

type Address struct {
    Road string
    Street string
    City string
    Province string
    Country string
}

Zhang3 := Student{
        Name: "张三",
        Age:  18,
        Address: Address{
            Road:     "renmin south road",
            Street:   "123 street",
            City:     "cs",
            Province: "hn",
            Country:  "CN",
        },
    }

将学生编码为 JSON 格式,我们可以使用 JSON 包中的 json.Marshl() 函数:

Info_of_Zhang3, err := json.Marshal(Zhang3)
if err == nil {
    fmt.Println(string(Info_of_Zhang3))
} else {
    fmt.Println(err)
    return
}

Marshal() 函数返回编码后的 JSON (字节切片)和 error 信息(如果出错的话)。然后我们可以打印 JSON 字符串。
完整代码如下:

package main

import (
    "encoding/json"
    "fmt"
)

type Student struct {
    Name    string
    Age     int
    Address Address
}

type Address struct {
    Road     string
    Street   string
    City     string
    Province string
    Country  string
}

func main() {

    Zhang3 := Student{
        Name: "张三",
        Age:  18,
        Address: Address{
            Road:     "renmin south road",
            Street:   "123 street",
            City:     "cs",
            Province: "hn",
            Country:  "CN",
        },
    }

    Info_of_Zhang3, err := json.Marshal(Zhang3)
    if err == nil {
        fmt.Println(string(Info_of_Zhang3))
    } else {
        fmt.Println(err)
        return
    }

}

运行代码,得到如下 JSON 数据结果:

$ go run main.go
{"Name":"张三","Age":18,"Address":{"Road":"renmin south road","Street":"123 street","City":"cs","Province":"hn","Country":"CN"}}

当你看 JSON 输出时,你可能已经注意到没有缩进。如果你想缩进输出并很好地格式化它,你可以使用json. MarshalIndent()函数。
比如,使用如下语句:

Info_of_Zhang3, err := json.MarshalIndent(Zhang3, "", "    ")

函数解析:第二个参数指定每行输出的开头的字符串。输出的开头,第三个参数指定每行要缩进的字符串。此时json.MarshalIndent(Zhang3, "", "    ")可以得到如下的输出:

{
    "Name": "张三",
    "Age": 18,
    "Address": {
        "Road": "renmin south road",
        "Street": "123 street",
        "City": "cs",
        "Province": "hn",
        "Country": "CN"
    }
}

接口转为 JSON 格式

有时您并不希望固定结构中的字段数量。 相反,您希望能够在需要的时候添加额外的数据。您可以使用空接口来实现这一点,如下所示:

type Student map[string] interface{}
type Address map[string] interface{}

使用空接口,可以创建自己的 Student 变量,还可以添加想要的元素,就像这样:

Zhang3 := Student{
    "Name": "张三",
    "Age": 18,
    "Address": Address{
        "Road": "renmin south road",
        "Street": "123 street",
        "City": "cs",
        "Province": "hn",
        "Country": "CN",
    },
    "Year": 2022,    // 新增学年
}

完整代码如下:

package main

import (
    "encoding/json"
    "fmt"
)

type Student map[string]interface{}
type Address map[string]interface{}

func main() {
    Zhang3 := Student{
        "Name": "张三",
        "Age":  18,
        "Address": Address{
            "Road":     "renmin south road",
            "Street":   "123 street",
            "City":     "cs",
            "Province": "hn",
            "Country":  "CN",
        },
        "Year":       2022, // 新增学年
        "GraduateAt": 2026, // 毕业年份
    }

    InfoOfZhang3, err := json.MarshalIndent(Zhang3, "", "    ")
    if err == nil {
        fmt.Println(string(InfoOfZhang3))
    } else {
        fmt.Println(err)
    }
}

代码输出结果为:

{
    "Address": {
        "City": "cs",
        "Country": "CN",
        "Province": "hn",
        "Road": "renmin south road",
        "Street": "123 street"
    },
    "Age": 18,
    "GraduateAt": 2026,
    "Name": "张三",
    "Year": 2022
}

同时我们能看到输出的 JSON 中的键的顺序是按字母排序的。

Marshal() 函数的原型

我们看一下 Marshal 函数:

func Marshal(v interface{}) ([]byte, error) {
   e := newEncodeState()

   err := e.marshal(v, encOpts{escapeHTML: true})
   if err != nil {
      return nil, err
   }
   buf := append([]byte(nil), e.Bytes()...)

   e.Reset()
   encodeStatePool.Put(e)

   return buf, nil
}

函数可以接收任意类型的接口数据 v,并转换为字节数组类型,返回值就是 JSON 数据和错误信息;若转换成功,则 err == nil;
在进行对象转换为JSON的过程中,会遵循一下几条原则:
a. 布尔型转换为JSON后仍然是布尔型;
b. 浮点型转换为JSON后里面的常规数字;
c. 字符串将以 UTF-8 编码转化输出为 Unicode 字符串,将特殊字符转义;
d. 数组和切片被转换为JSON里面的数组,[]byte类会被转换为 base64 编码后的字符串,slice的零值被转换为null;
e. 结构体转换为 JSON 对象,并且只有结构体内变量必须首字母大写,才可被导出的字段转化输出,而且这些字段会被作为 JSON 对象的字符串索引;
f. 转换一个 map 类型的数据结构时,该数据的类型必须时 map[string]T ,T 可以是encoding/json 包支持的任意类型。

总结

本文只是简单的把 Go 语言常见的结构体和接口转化为 JSON 数据,其他类型类似,最后给出了编码的函数 Marshal() 原型, 并简单进行了解释。

除此之外,encoding/json 包还提供了 Encode() 和 Decode() 函数用于单一对象的格式转化,而 Marshal() 和 Unmarshal() 函数工作于多个对象和字节流上。

其实,本文只是简单的介绍了 Go 语言和 JSON 数据在控制台的简单转化,等后续的文章介绍了文件读取和写入时,就可以学会与 JSON 文件打交道了。敬请期待!

到此这篇关于Go 转 JSON的文章就介绍到这了,更多相关Go 转 JSON内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Go 结构体、数组、字典和 json 字符串的相互转换方法

    Go 语言中 encoding/json 包可以很方便的将结构体.数组.字典转换为 json 字符串. 引用 import "encoding/json" 解析语法 // v 传入结构体.数组等实例变量 // []byte 字节数组 // error 可能会有的错误 func Marshal(v interface{}) ([]byte, error) 反解析 // []byte 字节数组 // v 传入结构体.数组等实例变量的指针地址 // error 可能会有的错误 func Un

  • golang struct, map, json之间的相互转换

    本文用于记录我在 golang 学习阶段遇到的类型转换问题,针对的是 json .map.struct 之间相互转换的问题,用到的技术 json .mapstructure.reflect 三个类库 公共代码区域 package main import ( "encoding/json" "fmt" "testing" ) type UserInfoVo struct { Id string `json:"id"` UserN

  • golang 实现json类型不确定时的转换

    将json转为结构体时,经常会遇到无法确定某个字段类型的情况.在Go中可以使用interface 任意类型来解决. // convert json to struct // type uncertain package main import ( "fmt" "encoding/json" ) type Host struct { Id interface{} IdcId interface{} } func main() { b := []byte(`{"

  • golang 实现struct、json、map互相转化

    一.Json和struct互换 (1)Json转struct例子: package main import ( "fmt" "encoding/json" ) type People struct { Name string `json:"name_title"` Age int `json:"age_size"` } func JsonToStructDemo(){ jsonStr := ` { "name_tit

  • Go语言中转换JSON数据简单例子

    Go语言转换JSON数据真是非常的简单. 以EasyUI的Demo为例,将/demo/datagrid/datagrid_data1.json 拷贝到$GOPATH/src目录: JSON.go: 复制代码 代码如下: package main import (         "encoding/json"         "fmt"         "io/ioutil" ) type product struct {         Pro

  • go json转换实践中遇到的坑

    在使用 go 语言开发过程中,经常需要使用到 json 包来进行 json 和 struct 的互相转换,在使用过程中,遇到了一些需要额外注意的地方,记录如下. 整数变浮点数问题 假设有一个 Person 结构,其中包含 Age int64 和 Weight float64 两个字段,现在通过 json 包将 Person 结构转为 map[string]interface{},代码如下. type Person struct { Name string Age int64 Weight flo

  • Go语言的数据结构转JSON

    目录 结构体转为 JSON 格式 接口转为 JSON 格式 Marshal() 函数的原型 总结 在日常工作中,除了需要从 JSON 转化为 Go 的数据结构.但往往相反的情况是:我们需要将数据以 JSON 字符串的形式发送到 Web 服务器.今天我们将学会如何从一个结构化数据编码为 JSON . Json(Javascript Object Nanotation)是一种数据交换格式,常用于前后端数据传输.任意一端将数据转换成json 字符串,另一端再将该字符串解析成相应的数据结构,如strin

  • C语言中数据结构之链表归并排序实例代码

    C语言中数据结构之链表归并排序实例代码 问题 设有两个无头结点的单链表,头指针分别为ha,hb,链中有数据域data,链域next,两链表的数据都按递增排序存放,现要求将hb表归到ha表中,且归并后ha仍递增序,归并中ha表中已有的数据若hb中也有,则hb中的数据不归并到ha中,hb的链表在算法中不允许破坏. 源程序 #include <stdio.h> #include<stdlib.h> #define N1 6 /*链表La的长度*/ #define N2 6 /*链表Lb的

  • C语言中数据结构之链式基数排序

    C语言中数据结构之链式基数排序 实现效果图: 实例代码: #include<stdio.h> #include<string.h> #include<stdlib.h> #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 typedef int Status; typedef int ElemType; #define MAX_NUM_OF_KEY 8 //关

  • Java语言实现数据结构栈代码详解

    近来复习数据结构,自己动手实现了栈.栈是一种限制插入和删除只能在一个位置上的表.最基本的操作是进栈和出栈,因此,又被叫作"先进后出"表. 首先了解下栈的概念: 栈是限定仅在表头进行插入和删除操作的线性表.有时又叫LIFO(后进先出表).要搞清楚这个概念,首先要明白"栈"原来的意思,如此才能把握本质. "栈"者,存储货物或供旅客住宿的地方,可引申为仓库.中转站,所以引入到计算机领域里,就是指数据暂时存储的地方,所以才有进栈.出栈的说法. 实现方式是

  • go语言使用第三方包 json化结构体操作示例

    本文实例讲述了go语言使用第三方包 json化结构体操作.分享给大家供大家参考,具体如下: 前提条件:安装好操作系统对应的git go get -u github.com/pquerna/ffjson -u参数:如果本地已经存在该包,则强制更新. 1.既然是把结构体转为json字符串,那么先来定义一个结构体 复制代码 代码如下: // 定义一个结构体 type NewsModel struct {  Id int  Title string } 2.且看ffjson这包用什么方法来把结构体转为j

  • C语言编程数据结构线性表之顺序表和链表原理分析

    目录 线性表的定义和特点 线性结构的特点 线性表 顺序存储 顺序表的元素类型定义 顺序表的增删查改 初始化顺序表 扩容顺序表 尾插法增加元素 头插法 任意位置删除 任意位置添加 线性表的链式存储 数据域与指针域 初始化链表 尾插法增加链表结点 头插法添加链表结点 打印链表 任意位置的删除 双向链表 测试双向链表(主函数) 初始化双向链表 头插法插入元素 尾插法插入元素 尾删法删除结点 头删法删除结点 doubly-Linked list.c文件 doubly-Linkedlist.h 线性表的定

  • C语言编程数据结构的栈和队列

    目录 栈 数组实现 标题全部代码 Stack_array.c Stack_array.h 初始化数组栈 满栈后扩容 是否为空栈 压栈和退栈 链表实现 stack_chain.h stack_chain.c 整个压栈流程 整个弹栈流程 出栈情况 队列 队列的实现 queue_chain.h queue_chain.c 一个结构体类型用于维护这个队列 概念流程图 入队列的实现 出队列的实现 是否空队 栈 栈是一种以后进先出为顺序对对象进行添加或删除的数据结构 对栈进行形象记忆就像是桌子上的一堆书或一

  • C利用语言实现数据结构之队列

    目录 一.链队列 二.链队的表示 三.链队的基本操作 1. 链队的初始化 2. 链队的销毁 3. 入队 4. 出队 四.顺序队列 五.循环队列 1. 初始化 2. 求队列长度 3. 入队 4. 出队 前言: 队列在生活中也比较常见,例如购物排队--新来的成员总是加入队尾,每次离开的成员总是队列头上的. 队列按存储方式可以分为两种:顺序队列和链队列. 一.链队列 链式队列中每个元素定义成一个结点,含数据域与指针域(指向下一结点),并设头尾指针.用图表示就是. 二.链队的表示 前面的链式结构,总是使

  • Go语言利用Unmarshal解析json字符串的实现

    简单的解析例子: 首先还是从官方文档中的例子: package main import (     "fmt"     "encoding/json" ) type Animal struct {     Name  string     Order string } func main() {     var jsonBlob = []byte(`[         {"Name": "Platypus", "Or

  • Javascript中扁平化数据结构与JSON树形结构转换详解

    目录 一. 先说简单的树形结构数扁平化处理 二. 再讲将扁平化数据结构转JSON树状形结构 扩充一个知识点:for in 与 for of 的区别 : 总结 不废话,直接开干 一. 先说简单的树形结构数扁平化处理 上思想: 思想:采用递归,每个对象都有childern,只要有children属性提取出来将其放在空数组中 然后将对象的其他属性解构出来,最后将数组合并 上代码: //已知JSON树状形结构的数据data let data = [ {id:1,title:'标题1',parent_id

随机推荐