structstruct

核心的两个函数

编码函数 Marshal

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

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

结构体转换为json

package main  
  
import (  
   "encoding/json"  
   "fmt")  
  
type Person struct {  
   Name  string  
   Age   int  
   Email string  
}  
  
func Marsha() {  
   p := Person{  
      Name:  "tom",  
      Age:   20,  
      Email: "tom@gmail.com",  
   }  
   b, _ := json.Marshal(p)  
   fmt.Printf("b: %v\n", string(b))  
}  
func main() {  
   Marsha()  
}

map 转换为json

package main  
  
import (  
   "encoding/json"  
   "fmt")  
  
type Person struct {  
   Name  string  
   Age   int  
   Email string  
}  
  
func Marsha() {  
   p := make(map[string]interface{}, 20)  
   p["名称"] = "张三"  
   p["性别"] = "男"  
   p["年龄"] = "18"  
   b, _ := json.Marshal(p)  
   fmt.Printf("b: %v\n", string(b))  
}  
func main() {  
   Marsha()  
}

解码函数 Unmarshal

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

将json转码成struct结构体 或是 map

此函数的关键点在与 v 的数据类型,但是建议还是使用 结构体作为 v 的类型,毕竟可以使用 tag 标签来更加精准的解析数据
特别注意:第二次参数必须传入地址,否则修改不成功

json 转 map

package main  
  
import (  
   "encoding/json"  
   "fmt")  
  
type Person struct {  
   Name  string  
   Age   int  
   Email string  
}  
  
func Marsha() []byte {  
   p := make(map[string]interface{}, 20)  
   p["名称"] = "张三"  
   p["性别"] = "男"  
   p["年龄"] = "18"  
   b, _ := json.Marshal(p)  
   return b  
}  
func Unmarshal(b []byte) {  
   var m map[string]interface{}  
   json.Unmarshal(b, &m)  
   fmt.Printf("%v\n", m)  
}  
func main() {  
   Unmarshal(Marsha())  
}

json转换为结构体

package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	Name   string
	Age    int
	Gender string
}

func Marsha() []byte {
	p := make(map[string]interface{}, 20)
	p["name"] = "张三"
	p["gender"] = "男"
	p["age"] = "18"
	b, _ := json.Marshal(p)
	return b
}
func Unmarshal(b []byte) {
	var m Person
	json.Unmarshal(b, &m)
	fmt.Printf("%v\n", m)
}
func main() {
	Unmarshal(Marsha())
}

解析嵌套类型

package main

import (
	"encoding/json"
	"fmt"
)

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

// 解析嵌套类型
func Unmarshal() {
	b := []byte(`{"Name":"tom","Age":20,"Email":"tom@gmail.com", "Parents":["tom", "kite"]}`)
	var f Person
	json.Unmarshal(b, &f)
	fmt.Printf("f: %v\n", f)
}
func main() {
	Unmarshal()
}

忽略字段

--

当然,如果你把变量名弄成小写,也是可以实现忽略的效果滴§( ̄▽ ̄

// 使用json tag指定json序列化与反序列化时的行为
type Person struct {
	Name   string `json:"name"` // 指定json序列化/反序列化时使用小写name
	Age    int64
	Weight float64 `json:"-"` // 指定json序列化/反序列化时忽略此字段
}

忽略空值字段

json.Marshal()intfloatstring""omitempty

举个例子:

type User struct {
	Name  string   `json:"name"`
	Email string   `json:"email"`
	Hobby []string `json:"hobby"`
}

func omitemptyDemo() {
	u1 := User{
		Name: "七米",
	}
	// struct -> json string
	b, err := json.Marshal(u1)
	if err != nil {
		fmt.Printf("json.Marshal failed, err:%v\n", err)
		return
	}
	fmt.Printf("str:%s\n", b)
}

输出结果:

str:{"name":"七米","email":"","hobby":null}

如果想要在最终的序列化结果中去掉空值字段,可以像下面这样定义结构体:

// 在tag中添加omitempty忽略空值
// 注意这里 hobby,omitempty 合起来是json tag值,中间用英文逗号分隔
type User struct {
	Name  string   `json:"name"`
	Email string   `json:"email,omitempty"`
	Hobby []string `json:"hobby,omitempty"`
}
omitemptyDemo
str:{"name":"七米"} // 序列化结果中没有email和hobby字段

忽略嵌套结构体空值字段

首先来看几种结构体嵌套的示例:

type User struct {
	Name  string   `json:"name"`
	Email string   `json:"email,omitempty"`
	Hobby []string `json:"hobby,omitempty"`
	Profile
}

type Profile struct {
	Website string `json:"site"`
	Slogan  string `json:"slogan"`
}

func nestedStructDemo() {
	u1 := User{
		Name:  "七米",
		Hobby: []string{"足球", "双色球"},
	}
	b, err := json.Marshal(u1)
	if err != nil {
		fmt.Printf("json.Marshal failed, err:%v\n", err)
		return
	}
	fmt.Printf("str:%s\n", b)
}
Profile
str:{"name":"七米","hobby":["足球","双色球"],"site":"","slogan":""}

想要变成嵌套的json串,需要改为具名嵌套或定义字段tag:

type User struct {
	Name    string   `json:"name"`
	Email   string   `json:"email,omitempty"`
	Hobby   []string `json:"hobby,omitempty"`
	Profile `json:"profile"`
}
// str:{"name":"七米","hobby":["足球","双色球"],"profile":{"site":"","slogan":""}}
omitempty
type User struct {
	Name     string   `json:"name"`
	Email    string   `json:"email,omitempty"`
	Hobby    []string `json:"hobby,omitempty"`
	Profile `json:"profile,omitempty"`
}
// str:{"name":"七米","hobby":["足球","双色球"],"profile":{"site":"","slogan":""}}

还需要使用嵌套的结构体指针:

type User struct {
	Name     string   `json:"name"`
	Email    string   `json:"email,omitempty"`
	Hobby    []string `json:"hobby,omitempty"`
	*Profile `json:"profile,omitempty"`
}
// str:{"name":"七米","hobby":["足球","双色球"]}

不修改原结构体忽略空值字段

UserUserPublicUserUserPasswordomitempty
type User struct {
	Name     string `json:"name"`
	Password string `json:"password"`
}

type PublicUser struct {
	*User             // 匿名嵌套
	Password *struct{} `json:"password,omitempty"`
}

func omitPasswordDemo() {
	u1 := User{
		Name:     "七米",
		Password: "123456",
	}
	b, err := json.Marshal(PublicUser{User: &u1})
	if err != nil {
		fmt.Printf("json.Marshal u1 failed, err:%v\n", err)
		return
	}
	fmt.Printf("str:%s\n", b)  // str:{"name":"七米"}
}