Go中json、map、struct的转换

  • json与map、json与struct的转换直接通过encoding/json报的序列化与反序列化就可以实现;
  • 但是map转struct可以通过github.com/mitchellh/mapstructure包来实现
  • json相比较转换为map,转换为struct在实际使用中更加方便;
    1. map需要通过 key 获取数据,可能出现不存在的 key,为了严谨,需要检查 key 是否存在;
    2. 相对于结构体的方式,map数据提取不便且不能利用 IDE 补全检查,key 容易写错;

json与struct的转换

type person struct {
	Name string `json:"name"` 
	Age  int    `json:"age"`  //``是为了指定转换为对应格式的字段名。json:"age"标识转json时该字段显示为age
}

//json与struct的转换
func main() {
	p1 := person{
		Name: "Bradley",
		Age:  18,
	}
	//序列化
	v, error := json.Marshal(p1)
	if error != nil {
		fmt.Printf("error is %v\n", error)
		return
	}
	fmt.Printf("%#v\n", string(v))//"{\"name\":\"Bradley\",\"age\":18}"
	//反序列化
	str := `{"name":"coope","age":20}`
	var p2 person
	//因为是传入函数且是修改  所以需要传入的是指针;Unmarshal对应的结构体字段首字母必须都是大写的
	json.Unmarshal([]byte(str), &p2)
	fmt.Printf("%#v\n", p2) //main.person{Name:"coope", Age:20}
}

直接通过json包的Marshal与Unmarshal就可以实现其互转,需要注意的是:
1.因为结构体会传入到Marshal,Unmarshal函数中所以字段必须是大写的才可以被别的包调用
2.Unmarshal时因为是传入函数且是修改 ,所以需要传入的是指针;

json与map的互转

func  main(){
	jsonStr := `
		{
			"resultcode": "200",
			"reason": "Return Successd!",
			"result": {
				"province": "浙江",
				"city": "杭州",
				"areacode": "0571",
				"zip": "310000",
				"company": "中国移动",
				"card": ""
			}
		}
	`
	//json转map
	var p1 map[string]interface{}
	err := json.Unmarshal([]byte(jsonStr), &p1)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(p1)
	//map[reason:Return Successd! result:map[areacode:0571 card: city:杭州 company:中国移动 province:浙江 zip:310000] resultcode:200]

	//map转json
	p:=make(map[string]interface{})
	p["resultcode"]=200
	p["reason"]="Return Successd!"
	marshal, err := json.Marshal(p)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(string(marshal))//{"reason":"Return Successd!","resultcode":200}

}

直接通过json包的Marshal与Unmarshal就可以实现其互转,需要注意的是:Unmarshal时因为是传入函数且是修改 ,所以需要传入的是指针;

struct与map的互转

map转struct

func main(){
	p:=make(map[string]interface{})
	p["rc"]=200
	p["rs"]="Return Successd!"
	in:= struct {
		Resultcode int `mapstructure:"rc"`
		Reason string `mapstructure:"rs"`
	}{}
	_ = mapstructure.Decode(p, &in)
	fmt.Println(in) //{200 Return Successd!}
}
  1. 使用mapstructure包直接将map转为struct;
  2. 可以使用tag:mapstructure来使struct中的字段与map中字段做映射
    3.这里推荐一个直接将json转换为struct的网站:https://mholt.github.io/json-to-go/
    在这里插入图片描述

struct转map

type User struct {
	 	Id        int    `json:"id"`
	    Username    string    `json:"username"`
	 	Password    string    `json:"password"`
	 }
user := User{5, "zhangsan", "password"}
marshal, _ := json.Marshal(user)
var pp map[string]interface{}
_ = json.Unmarshal([]byte(marshal), &pp)
fmt.Println(pp)//map[id:5 password:password username:zhangsan]

struct转map;可以先将struct序列化后再将其反序列化到map中;也可以通过反射实现转换

总结:

  1. 在实际的使用中可能不确定json 格式的数据具体类型;
    可是使用mapstructure中的弱类型解析方法:WeakDecode()
    官方案例:
type AutoGenerated struct {
	Type     string `json:"type"`
	Database string `json:"database"`
	Table    string `json:"table"`
	Data     []struct {
		BlogID  int `json:"blogId"`
		Title   string `json:"title"`
		Content string `json:"content"`
		UID     int `json:"uid"`
		State   int `json:"state"`
	} `json:"data"`
}
func main(){
	jsonStr:=`{
    "type": "UPDATE",
    "database": "blog",
    "table": "blog",
    "data": [
        {
            "blogId": "100001",
            "title": "title",
            "content": "this is a blog",
            "uid": "1000012",
            "state": "1"
        }
    ]
}`
	m1:=make(map[string]interface{})
	 json.Unmarshal([]byte(jsonStr), &m1)
	fmt.Println(m1)
	var output AutoGenerated
	//mapstructure.Decode(m1,&output)
	//fmt.Println(output)  //{UPDATE blog blog [{0 title this is a blog 0 0}]}  //int类型没有解析
	mapstructure.WeakDecode(m1,&output)
	fmt.Println(output)//{UPDATE blog blog [{100001 title this is a blog 1000012 1}]} 弱类型解析
}
  1. 在实际的使用中可能data中参数并不固定
    参考mapstructure中的案例方法:
type Family struct {
	LastName string `mapstructure:"Ln"`
}
type Location struct {
	City string
}
type Person struct {
	Family    `mapstructure:",squash"`
	Location  `mapstructure:",squash"`
	FirstName string
}

func main() {
	input := map[string]interface{}{
		"FirstName": "Mitchell",
		"Ln":  "Hashimoto",
		"City":      "San Francisco",
	}

	var result Person
	err := mapstructure.Decode(input, &result)
	if err != nil {
		panic(err)
	}
	fmt.Println(result.FirstName)
	fmt.Println(result.LastName)
	fmt.Println(result.City)
	/*
	Mitchell
	Hashimoto
	San Francisco
	*/
}

猜你喜欢

转载自blog.csdn.net/wzb_wzt/article/details/107846066