资料总结 资料总结
首页
go
java
云原生
  • mysql
  • redis
  • MongoDB
  • 设计模式详解
  • 数据结构与算法
  • 前端
  • 项目
  • 理论基础
  • 运营
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

linghui Wu

一只努力学飞的鱼
首页
go
java
云原生
  • mysql
  • redis
  • MongoDB
  • 设计模式详解
  • 数据结构与算法
  • 前端
  • 项目
  • 理论基础
  • 运营
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • go入门教程

  • go标准库

    • fmt标准库
    • os标准库
    • time标准库
    • log标准库
    • errors标准库
    • bytes标准库
    • io标准库
    • ioutil标准库
    • bufio标准库
    • builtin标准库
    • json标准库
      • 1. 核心函数
        • 1.1 Marshal
        • 1.2 Unmarshal
      • 2. 核心结构
        • 2.1 Decoder
        • 2.2 Encoder
        • 奇怪的需求
      • 我使用golang语言进行json解析,第一层的key是变化的,再第二层的结果才能转化成结构体
      • golang反序列化json,在json中不存在的字段设置默认值,如果json有就以json为主
        • 参考资料
    • sort标准库
    • math标准库
    • flag标准库
    • runtime标准库
    • context标准库
  • go常用第三方类库

  • ORM框架

  • web框架

  • 移动端

  • go
  • go标准库
wulinghui
2023-01-22
目录

json标准库

# json标准库

json包可以实现json的编码和解码,就是将json字符串转换为struct,或者将struct转换为json。

# 1. 核心函数

# 1.1 Marshal

func Marshal(v any) ([]byte, error)
1

将struct编码成json,可以接收任意类型

  • 布尔型转换为 JSON 后仍是布尔型,如true -> true
  • 浮点型和整数型转换后为JSON里面的常规数字,如 1.23 -> 1.23
  • 字符串将以UTF-8编码转化输出为Unicode字符集的字符串,特殊字符比如<将会被转义为\u003c
  • 数组和切片被转换为JSON 里面的数组,[]byte类会被转换为base64编码后的字符串,slice的零值被转换为null
  • 结构体会转化为JSON对象,并且只有结构体里边以大写字母开头的可被导出的字段才会被转化输出,而这些可导出的字段会作为JSON对象的字符串索引
  • 转化一个map 类型的数据结构时,该数据的类型必须是 map[string]T(T 可以是encoding/json 包支持的任意数据类型)
package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	Name  string
	Age   int
	Email string
}

func main() {
	p := Person{
		Name:  "zhangsan",
		Age:   20,
		Email: "zhangsan@mail.com",
	}
	b, _ := json.Marshal(p)
	fmt.Printf("b: %v\n", string(b))
}

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

# 1.2 Unmarshal

func Unmarshal(data []byte, v any) error
1

将json转码为struct结构体

这个函数会把传入的 data 作为一个JSON来进行解析,解析后的数据存储在参数 v 中。这个参数 v 也是任意类型的参数(但一定是一个类型的指针),原因是我们在是以此函数进行JSON 解析的时候,这个函数不知道这个传入参数的具体类型,所以它需要接收所有的类型。

package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	Name  string
	Age   int
	Email string
}

func main() {
	b := []byte(`{"Name":"zhangsan","Age":20,"Email":"zhangsan@mail.com"}`)
	var m Person
	json.Unmarshal(b, &m)
	fmt.Printf("m: %v\n", m)
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 2. 核心结构

# 2.1 Decoder

type Decoder struct {
    // contains filtered or unexported fields
}

1
2
3
4

从输入流读取并解析json,应用于io流Reader Writer可以扩展到http websocket等场景

package main

import (
	"encoding/json"
	"fmt"
	"os"
)

func main() {
	f, _ := os.Open("test.json")
	defer f.Close()

	d := json.NewDecoder(f)
	var v map[string]interface{}
	d.Decode(&v)

	fmt.Printf("v: %v\n", v)
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 2.2 Encoder

type Encoder struct {
    // contains filtered or unexported fields
}

1
2
3
4

写json到输出流,应用于io流Reader Writer可以扩展到http websocket等场景

package main

import (
	"encoding/json"
	"os"
)

type Person struct {
	Name   string
	Age    int
	Email  string
	Parent []string
}

func main() {
	p := Person{
		Name:   "zhangsan",
		Age:    20,
		Email:  "zhangsan@mail.com",
		Parent: []string{"Daddy", "Mom"},
	}
	f, _ := os.OpenFile("test.json", os.O_WRONLY, 077)
	defer f.Close()

	d := json.NewEncoder(f)
	d.Encode(p)
}

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

# 奇怪的需求

# 我使用golang语言进行json解析,第一层的key是变化的,再第二层的结果才能转化成结构体

    /*
    在Go语言中,如果你遇到第一层的key是变化的,需要第二层才能确定结构体的情况,你可以使用map[string]interface{}来处理。
    下面是一个示例代码,展示了如何解析具有变化的第一层key的JSON数据,并在第二层将其转换为结构体:
    */
	var result map[string]interface{} 
	err := json.Unmarshal([]byte(msg), &result)
	if err != nil {
		log.Printf("unmarshal websocket-msg failed err: %s\n", err)
		return
	}
    // 操作第二层的数据用于结构化数据。
	cfgs := &startup.FrpConfig{}
	commonValue, _ := json.Marshal(result["common"])
	err = json.Unmarshal(commonValue, &cfgs.Common)
	if err != nil {
		log.Printf("unmarshal websocket-msg key is common failed err: %s\n", err)
		return
	}
	// key是变化的。
	socksKey := s.Uuid + "_s5"
	socksValue, _ := json.Marshal(result[socksKey])
	err = json.Unmarshal(socksValue, &cfgs.Socks5)
	if err != nil {
		log.Printf("unmarshal websocket-msg key is %s failed err: %s\n", socksKey, err)
		return
	}
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

# golang反序列化json,在json中不存在的字段设置默认值,如果json有就以json为主

这个需要在框架层是做不了的,只在业务通过if判断来操作。

# 参考资料

一文带你了解Go语言如何解析JSON (opens new window)

编辑 (opens new window)
上次更新: 2023/09/07, 15:38:47
builtin标准库
sort标准库

← builtin标准库 sort标准库→

最近更新
01
架构升级踩坑之路
02-27
02
总结
02-27
03
语法学习
02-27
更多文章>
| Copyright © 2021-2025 Wu lingui |
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式