目录
  • 前言
  • 1. 结构体与JSON互转
  • 2. map与JSON互转
  • 3. 结构体的变量不加tag标签能否正常转成json数据
  • 4. JSON操作的一些小技巧
    • (1)忽略掉 struct 指定字段
    • (2)添加额外的字段
    • (3)合并两个 struct
    • (4)字符串传递给 int类型
    • (5)一个 json 分成两个struct
  • 补充:GoLang json格式化输出
    • 总结

      前言

      JSON是一种轻量级的数据交换格式。易于阅读和编写。 golang 提供了 encoding/json 包来操作JSON数据。

      1. 结构体与JSON互转

      (1)使用 json.Marshal() 方法,把结构体转成 JSON字符串

      import (
      	"encoding/json"
      	"fmt"
      )
      
      type Student struct {
      	Name string
      	Age int
      	Skill string
      }
      
      func main()  {
      	stu := Student{"tom", 12, "football"}
      	data, err := json.Marshal(&stu)
      	if err != nil {
      		fmt.Printf("序列化错误 err=%v\n", err)
      		return
      	}
      	fmt.Println("序列化后: ", string(data))
      }
      

      打印: 序列化后: {“Name”:“tom”,“Age”:12,“Skill”:“football”}

      (2)JSON字符串 转 结构体,可以使用 json.Unmarshal()方法

      func main()  {
      	str := `{"Name":"tom","Age":12,"Skill":"football"}`
      	var stu2 Student
      	err := json.Unmarshal([]byte(str), &stu2)
      	if err != nil {
      		fmt.Printf("反序列化错误 err=%v\n", err)
      		return
      	}
      	fmt.Printf("反序列化后: Student=%v, Name=%v\n", stu2, stu2.Name)
      }
      

      打印: 反序列化后: Student={tom 12 football}, Name=tom

      (3)如何实现结构体序列化后key的名称能自定义

      对于自定义key的名称,可以给 struct变量指定一个tag标签

      type Student struct {
      	Name string   `json:"stu_name"`
      	Age int       `json:"stu_age"`
      	Skill string  // 也可以不指定 tag标签,默认就是 变量名称
      }
      
      func main()  {
      	stu := Student{"tom", 12, "football"}
      	data, err := json.Marshal(&stu)
      	if err != nil {
      		fmt.Printf("序列化错误 err=%v\n", err)
      		return
      	}
      	fmt.Println("序列化后: ", string(data))
      }
      

      打印后,可以看到 key的名称已经变成了我们指定的 tag标签 的名称

      序列化后: {“stu_name”:“tom”,“stu_age”:12,“Skill”:“football”}

      2. map与JSON互转

      func main()  {
      	// map 转 Json字符串
      	m := make(map[string]interface{})
      	m["name"] = "jetty"
      	m["age"] = 16
      
      	data, err := json.Marshal(&m)
      	if err != nil {
      		fmt.Printf("序列化错误 err=%v\n", err)
      		return
      	}
      	fmt.Println("序列化后: ", string(data))    // 打印: 序列化后:  {"age":16,"name":"jetty"}
      
      	// Json字符串 转 map
      	str := `{"age":25,"name":"car"}`
      	err = json.Unmarshal([]byte(str), &m)
      	if err != nil {
      		fmt.Printf("反序列化错误 err=%v\n", err)
      		return
      	}
      	fmt.Printf("反序列化后: map=%v, name=%v\n", m, m["name"])
      	// 打印: 反序列化后: map=map[age:25 name:car], name=car
      }
      

      3. 结构体的变量不加tag标签能否正常转成json数据

      如果变量首字母小写,则为private。因为取不到反射信息,不能转。

      如果变量首字母大写,则为public。不管加不加 tag 都能正常转,加了tag的变量就按照tag的名称显示。

      示例:

      type User struct {
      	Name string    `json:"u_name"`
      	age int        `json:"u_age"`
      	Skill string   // 也可以不指定 tag标签,默认就是 变量名称
      	addr string
      }
      
      func main()  {
      	user := User{"admin", 23, "football", "上海"}
      	data, err := json.Marshal(&user)
      	if err != nil {
      		fmt.Printf("序列化错误 err=%v\n", err)
      		return
      	}
      	fmt.Println("序列化后: ", string(data))  // 打印: 序列化后:  {"u_name":"admin","Skill":"football"}
      }
      

      通过打印,我们发现小写的变量,如 age、addr 都没有转成 json数据。

      总结:

      首字母小写的不管加不加tag都不能转为json数据,而大写的加了tag可以取别名,不加tag则json内的字段跟结构体变量原名一致

      4. JSON操作的一些小技巧

      (1)忽略掉 struct 指定字段

      type User struct {
      	Name string    `json:"u_name"`
      	Password string `json:"password"`
      	Email string `json:"email"`
      }
      
      func main()  {
      	user := User{"admin", "pwd", "user@163.com"}
      	person := Person{23, "上海"}
      	// 忽略掉 Password 字段
      	data, _ := json.Marshal(struct {
      		*User
      		Password string `json:"password,omitempty"`
      	}{User: &user})
      	fmt.Println("忽略字段: ", string(data))  // 打印: 忽略字段: {"u_name":"admin","email":"user@163.com"}
      }
      

      忽略字段: {“u_name”:“admin”,“email”:“user@163.com”}}

      (2)添加额外的字段

      data, _ = json.Marshal(struct {
      	*User
      	Skill string `json:"skill"`  // 临时添加额外的 Skill字段
      }{
      	User: &user,
      	Skill: "football",
      })
      
      fmt.Println("添加额外字段: ", string(data))
      

      添加额外字段: {“u_name”:“admin”,“password”:“pwd”,“email”:“user@163.com”,“skill”:“football”}

      (3)合并两个 struct

      type User struct {
      	Name string    `json:"u_name"`
      	Password string `json:"password"`
      	Email string `json:"email"`
      }
      
      type Person struct {
      	Age int
      	Addr string `json:"addr"`
      }
      
      func main()  {
          // 初始化两个 struct
      	user := User{"admin", "pwd", "user@163.com"}
      	person := Person{23, "上海"}
      	
      	data, _ := json.Marshal(struct {
      		*User
      		*Person
      	}{
      		User: &user,
      		Person: &person,
      	})
      	
      	fmt.Println("合并两个struct: ", string(data))
      }
      

      合并两个struct: {“u_name”:“admin”,“password”:“pwd”,“email”:“user@163.com”,“Age”:23,“addr”:“上海”}

      (4)字符串传递给 int类型

      emp := struct {                    // 创建匿名 struct
      	Num int `json:"num,string"`
      }{15,}
      data, _ := json.Marshal(&emp)
      fmt.Println("数字转成字符串: ", string(data))       // 数字转成字符串: {"num":"15"}
      
      str := `{"Num":"25"}`
      _ = json.Unmarshal([]byte(str), &emp)
      fmt.Printf("字符串转成数字: Emp.Num=%v\n", emp.Num) // 字符串转成数字: Emp.Num=25
      

      (5)一个 json 分成两个struct

      str = ` {"u_name":"system","password":"abc","email":"user2@163.com","Age":23,"addr":"杭州"}`
      var user2 User
      var person2 Person
      _ := json.Unmarshal([]byte(str), &struct {
      	*User
      	*Person
      }{
      	User: &user2,
      	Person: &person2,
      })
      
      fmt.Printf("分成两个struct: User=%v, Person=%v\n", user2, person2)
      

      分成两个struct: User={system abc user2@163.com}, Person={23 杭州}

      补充:GoLang json格式化输出

      简单记录一下go语言json格式化输出的办法

      import (
          "bytes"
          "encoding/json"
          "fmt"
          "os"
      )
      
      type Complex_Type struct{
          Age int `json:"age"`
          Name string `json:"name"`
          Grades map[string]int `json:"grade"`
          Parents []string `json:"parents"`
      }
      
          grades := map[string]int{
              "math" : 96,
              "chinese" : 87,
              "english" : 93,
          }
      
          parents := []string{
              "minato",
              "kushina",
          }
      
          complex_type := Complex_Type{
              Age: 18,
              Name: "Naruto",
              Grades : grades,
              Parents: parents,
          }
          res,err := json.Marshal(complex_type)
          exitOnError(err)
          var out bytes.Buffer
          err = json.Indent(&out,res,"","\t")
          out.WriteTo(os.Stdout)
          fmt.Printf("\n")

      输出:

      golang中json操作的完全指南

      总结

      声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。