二丫讲梵 二丫讲梵
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)

二丫讲梵

行者常至,为者常成
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)
  • Shell编程

  • Go编程笔记

  • 前端编程笔记

  • Go学习笔记

    • 基础部分

      • 基础知识
      • 数据类型
      • fmt的格式化输入输出
      • 运算符
      • 流程控制
      • 认识函数
      • 包的操作
      • 项目工程-在同级目录
      • 指针(pointer)
      • 数组(array)
      • 切片(slice)
      • 字典(map)
      • 结构体(struct)
      • 匿名组合
      • 方法
      • 接口
      • error接口
      • panic
      • recover
      • 字符串操作
      • 字符串转换
      • 正则表达式
      • JSON处理
        • 1,编码 json
          • 1,通过结构体生成 JSON
          • 1,示例代码
          • 2,几个技巧。
          • 2,通过 map 生成 json。
        • 2,解码 json
          • 1,json 解析为结构体。
          • 2,json 解析为 map。
      • 文件的操作
      • goroutine
      • channel
      • select
      • sync-lock锁
      • 网络概述
      • Socket编程
      • 发文件与聊天室
      • http编程
      • 爬虫实战
      • 单元测试了解
    • web框架

    • orm框架

  • Vue-21年学习笔记

  • Vue-22年重学笔记

  • 编程世界
  • Go学习笔记
  • 基础部分
二丫讲梵
2021-07-10
目录

JSON处理

文章发布较早,内容可能过时,阅读注意甄别。

# 1,编码 json

JSON(JavaScript Object Notation)是一种比 XML 更轻量级的数据交换格式,在易于人们阅读和编写的同时,也易于程序解析和生成。尽管 JSON 是 JavaScript 的一个子集,但 JSON 采用完全独立于编程语言的文本格式,且表现为键/值对集合的文本描述形式(类似一些编程语言中的字典结构),这使它成为较为理想的,跨平台,跨语言的数据交换语言。

{
  "Company": "itcast",
  "Subjects": ["Go", "C++", "Python", "Test"],
  "Isok": true,
  "Price": 666
}
1
2
3
4
5
6

开发者可以用 JSON 传输简单的字符串,数字,布尔值,也可以传输一个数组,或者一个更复杂的复合结构。在 web 开发领域中,JSON 被广泛应用于 web 服务端程序和客户端之间的数据通信。

Go 语言内建对 JSON 的支持。使用 Go 语言内置的encoding/json标准库,开发者可以轻松使用 Go 程序生成和解析 JSON 格式的数据。

JSON 官方网站:http://www.json.org 在线格式化:http://www.json.cn

# 1,通过结构体生成 JSON

使用 json.Marshal()函数可以对一组数据进行 JSON 格式的编码。 json.Marshal()函数的声明如下:

	func Marshal(v interface{}) ([]byte, error)
1

还有一个格式化输出:

	// MarshalIndent 很像 Marshal,只是用缩进对输出进行格式化
	func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)
1
2

# 1,示例代码

package main

import (
	"encoding/json"
	"fmt"
)

/*
{
    "Company":"itcast",
    "Subjects":[
        "Go",
        "C++",
        "Python",
        "Test"
    ],
    "Isok":true,
    "Price":666.66
}
*/

type It struct {
	Company  string		//注意变量名称必须是大写开头
	Subjects []string
	Isok     bool
	Price    float64
}

func main() {
	//定义一个结构体变量,同时初始化
	s := It{"itcast", []string{"Go", "C++", "Python", "Test"}, true, 666.66}
	//根据内容生成json文本的过程,叫编码
	//通过json文本解析成内容的过程,叫解码
	//buf, err := json.Marshal(s)
	//以上定义方式输出结果: buf =  {"Company":"itcast","Subjects":["Go","C++","Python","Test"],"Isok":true,"Price":666.66}

	buf, err := json.MarshalIndent(s, "", " ") //格式化编码
	if err != nil {
		fmt.Println("err = ", err)
		return
	}
	fmt.Println("buf = ", string(buf))

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

输出结果:

$ go run 11_通过结构体生成json.go
buf =  {
 "Company": "itcast",
 "Subjects": [
  "Go",
  "C++",
  "Python",
  "Test"
 ],
 "Isok": true,
 "Price": 666.66
}
1
2
3
4
5
6
7
8
9
10
11
12

# 2,几个技巧。

我们看到上面的输出字段名的首字母都是大写的,如果你想用小写的首字母怎么办呢?把结构体的字段名改成首字母小写的?JSON 输出的时候必须注意,只有导出的字段(首字母是大写)才会被输出,如果修改字段名,那么就会发现什么都不会输出,所以必须通过 struct tag 定义来实现。

针对 JSON 的输出,我们在定义 struct tag 的时候需要注意的几点是:

  • 字段的 tag 是”-“,那么这个字段不会输出到 JSON
  • tag 中带有自定义名称,那么这个自定义名称会出现在 JSON 的字段名中
  • tag 中如果带有”omitempty”选项,那么如果该字段值为空,就不会输出到 JSON 串中
  • 如果字段类型是 bool, string, int, int64 等,而 tag 中带有”,string”选项,那么这个字段在输出到 JSON 的时候会把该字段对应的值转换成 JSON 字符串
package main

import (
	"encoding/json"
	"fmt"
)

type It struct {
	Company  string   `json:"company"` //二次编码,可以将变量名称转为小写
	Subjects []string `json:"-"`       //表示这个字段不会输出打印
	Isok     bool     `json:",string"` //表示先转换为字符串,再输出到屏幕
	Price    float64  `json:"price, omitempty"` //如果Price为空,则不输出到json串当中
}

func main() {
	//定义一个结构体变量,同时初始化
	s := It{"itcast", []string{"Go", "C++", "Python", "Test"}, true, 666.66}
	//根据内容生成json文本的过程,叫编码
	//通过json文本解析成内容的过程,叫解码
	//buf, err := json.Marshal(s)
	//以上定义方式输出结果: buf =  {"Company":"itcast","Subjects":["Go","C++","Python","Test"],"Isok":true,"Price":666.66}

	buf, err := json.MarshalIndent(s, "", " ") //格式化编码
	if err != nil {
		fmt.Println("err = ", err)
		return
	}
	fmt.Println("buf = ", string(buf))

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

输出结果:

$ go run 11_通过结构体生成json.go
buf =  {
 "company": "itcast",
 "Isok": "true",
 "Price": "666.66"
}
1
2
3
4
5
6

# 2,通过 map 生成 json。

package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	//创建一个map
	m := make(map[string]interface{}, 4)
	m["Company"] = "itcast"
	m["Subjects"] = []string{"Go", "C++", "Python", "Test"}
	m["isok"] = true
	m["price"] = 666.666

	//编码成json
	//result, err := json.Marshal(m)
	result, err := json.MarshalIndent(m, "", "	")
	if err != nil {
		fmt.Println("err = ", err)
		return
	}
	fmt.Println("result = ", string(result))

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 2,解码 json

可以使用 json.Unmarshal()函数将 JSON 格式的文本解码为 Go 里面预期的数据结构。

json.Unmarshal()函数的原型如下:

	func Unmarshal(data []byte, v interface{}) error
1

该函数的第一个参数是输入,即 JSON 格式的文本(比特序列),第二个参数表示目标输出容器,用于存放解码后的值。

# 1,json 解析为结构体。

package main

import (
	"encoding/json"
	"fmt"
)

type It struct {
	Company  string   `json:"company"`
	Subjects []string `json:"subjects"`
	Isok     bool     `json:"isok"`
	Price    float64  `json:"price"`
}

func main() {
	jsonbuf := `
	{
 "company": "itcast",
 "subjects": [
  "Go",
  "C++",
  "Python",
  "Test"
 ],
 "isok": true,
 "price": 666.66
}`

	var tmp It
	err := json.Unmarshal([]byte(jsonbuf), &tmp)
	if err != nil {
		fmt.Println("err = ", err)
		return
	}
	//fmt.Println("tmp = ", tmp)
	fmt.Printf("tmp = %+v\n", tmp) //以详细格式输出

	//如果不想要某些字段输出,那么只需要在定义结构体的时候略掉即可
	type It1 struct {
		Subjects []string `json:"subjects"`
	}
	var tmp1 It1
	err = json.Unmarshal([]byte(jsonbuf), &tmp1)
	if err != nil {
		fmt.Println("err = ", err)
		return
	}

	fmt.Printf("tmp1 = %+v\n", tmp1) //以详细格式输出

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

# 2,json 解析为 map。

package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	jsonbuf := `
	{
 "company": "itcast",
 "subjects": [
  "Go",
  "C++",
  "Python",
  "Test"
 ],
 "isok": true,
 "price": 666.66
}`
	//创建一个map

	m := make(map[string]interface{}, 4)
	err := json.Unmarshal([]byte(jsonbuf), &m)
	if err != nil {
		fmt.Println("err = ", err)
		return
	}
	fmt.Printf("m = %+v\n", m) //以详细格式输出

	// var str string
	// str = string(m["company"])
	// fmt.Println("str = ", str) //err,无法转换类型

	//类型断言
	for key, value := range m {
		switch data := value.(type) {
		case string:
			fmt.Printf("map[%s]的类型为string,value = %s\n", key, data)
		case bool:
			fmt.Printf("map[%s]的类型为bool,value = %v\n", key, data)
		case float64:
			fmt.Printf("map[%s]的类型为float64,value = %v\n", key, data)
		// case []string:
		// 	fmt.Printf("map[%s]的类型为[]string,value = %v\n", key, data) //不会打印结果
		case []interface{}:
			fmt.Printf("map[%s]的类型为[]interface{},value = %v\n", key, data) //接着还可以对其进行迭代打印

		}
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

运行结果:

$ go run 14_json解析成map.go
m = map[company:itcast subjects:[Go C++ Python Test] isok:true price:666.66]
map[company]的类型为string,value = itcast
map[subjects]的类型为[]interface{},value = [Go C++ Python Test]
map[isok]的类型为bool,value = true
map[price]的类型为float64,value = 666.66
1
2
3
4
5
6
微信 支付宝
#go
上次更新: 2024/06/13, 22:13:45
正则表达式
文件的操作

← 正则表达式 文件的操作→

最近更新
01
学习周刊-总第213期-2025年第22周
05-29
02
学习周刊-总第212期-2025年第21周
05-22
03
从赵心童世锦赛夺冠聊聊我的斯诺克情缘
05-16
更多文章>
Theme by Vdoing | Copyright © 2017-2025 | 点击查看十年之约 | 浙ICP备18057030号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式