Go语言中结构体与JSON之间互相转换

JSON

JSON是一种轻量级的数据交换格式。

易于人阅读和编写。同时也易于机器解析和生成。

restfull Api 接口中返回的数据都是json数据

结构体中的私有属性不能被json序列化

因为:结构体中的私有属性不能被json序列化,所以结构体中的属性必须是公有的。要大写。

结构体与JSON序列化

比如我们Golang要给 App 提供Api接口数据,

这个时候就需要涉及到结构体和Json之间的相互转换。

Golang JSON序列化是指:把结构体数据转化成JSON格式的字符串

Golang JSON 的反序列化是指:把JSON格式的字符串转化成Golang中的结构体数据

将结构体转换为JSON字符串

复制代码
package main
import (
	"encoding/json"
	"fmt"
)
type Student struct {
	Name string
	Age int
}
func main()  {
	var s1 = Student{
		Name: "张三",
		Age: 18,
	}
	// json.Marshal 返回 []byte,也就是字节切片。不是 string,你需要的是字符串,所以需要转换一下
	jsonByte, _ := json.Marshal(s1)
	jsonStr := string(jsonByte)
	fmt.Printf("%s",jsonStr)	
}

输出的值是:{"Name":"张三","Age":18}

jsonStr := string(jsonByte) 为啥要转换一下?

因为:json.Marshal 返回 \[\]byte,也就是字节切片。

不是 string, 你需要的是字符串,所以需要转换一下。

结构体中的字段是小写能正常被json序列化

如果结构体中的字段是小写的,那么这个字段就不能被json序列化。

也就是这个字段会被丢失。

复制代码
package main

import (
	"encoding/json"
	"fmt"
)

type Student struct {
	Name string
	Age  int
    // sex 是小写的,所以不能被json序列化。
	sex  string
}

func main() {
	var s1 = Student{
		Name: "张三",
		Age:  18,
		sex:  "男",
	}
	// json.Marshal 返回 []byte,也就是字节切片。不是 string,你需要的是字符串,所以需要转换一下
	jsonByte, _ := json.Marshal(s1)
	jsonStr := string(jsonByte)
	fmt.Printf("%s", jsonStr)
}

{"Name":"张三","Age":18}

sex 字段在序列化的时候会被丢失。

如何在序列化的时候将字段变成小写

如果要将字段变成小写,那么在结构体中字段的标签中添加 json:"字段名" 即可。

复制代码
package main
import (
	"encoding/json"
	"fmt"
)
type Student struct {
	// 在JSON序列化的时候将他们变成小写
	Name string `json:"name"`
	Age  int    `json:"age"`
	Sex  string `json:"sex"`
}

func main() {
	var s1 = Student{
		Name: "张三",
		Age:  18,
		Sex:  "男",
	}
	// json.Marshal 返回 []byte,也就是字节切片。不是 string,你需要的是字符串,所以需要转换一下
	jsonByte, _ := json.Marshal(s1)
	jsonStr := string(jsonByte)
	fmt.Printf("%s", jsonStr)
}

输出的是:{"name":"张三","age":18,"sex":"男"}

结构体中的嵌套结构体,然后添加属性,最后转化为JSON字符串

复制代码
package main
import (
	"encoding/json"
	"fmt"
)
type Student struct {
	Name string
	Age  int
	Sex  string
}
type Class struct {
	Title    string
	Students []Student
}
func main() {
	c1 := Class{
		Title:    "1班",
		Students: make([]Student, 0),
	}
	for i := 0; i < 3; i++ {
		c1.Students = append(c1.Students, Student{
			Name: fmt.Sprintf("张三%d", i),
			Age:  18,
			Sex:  "男",
		})
	}

	jsonByte, _ := json.Marshal(c1)
	jsonStr := string(jsonByte)
	fmt.Printf("%s", jsonStr)
}

最后输出的是:

{

"Title":"1班",

"Students":[

{"Name":"张三0","Age":18,"Sex":"男"},

{"Name":"张三1","Age":18,"Sex":"男"},

{"Name":"张三2","Age":18,"Sex":"男"}

]

}

字符串转换为结构体

复制代码
package main
import (
	"encoding/json"
	"fmt"
)
type Student struct {
	Name string
	Age int
}
func main()  {
	// 生成一个JSON字符串
	jsonStr := `{"Name":"张三","Age":18}`
	// 反序列化
	var s1 Student
	// 需要注意写的是:&s1 而不是 s1,
	// 因为: json.Unmarshal 它的第二个参数要求传入一个指针,因此写成:&s1
	err := json.Unmarshal([]byte(jsonStr), &s1)	 
	if err != nil {
		fmt.Printf("反序列化失败:%v", err)
		return
	}
	fmt.Printf("%#v",s1)
}

输出的是: main.Student{Name:"张三", Age:18}