json Tag
type Student struct {
Name string `json:"name"`
Age int32 `json:"age"`
Class string `json:"class"`
}
Tag就是跟在结构体成员之后单引号中的内容,它的作用是用来当结构体对象进行编解码时,提供编/解码的方案。
举例说明:
package main
import (
"fmt"
"encoding/json"
)
type Student struct {
Name string
Age int32
Class string
}
func main() {
stu := Student {
Name: "ahaoozhang",
Age: 18,
Class: "电信1605班",
}
json, _ := json.Marshal(stu) //对stu结构体进行json编码
fmt.Println(string(json)) //打印json字符串
}
//执行的结果为:
// {"Name":"ahaoozhang","Age":18,"Class":"电信1605班"}
注意这种情况是在不包含jsonTag的情况下的编码结果,可以看出json字符串中的key与结构体成员名完全相同(包括大小写)。
package main
import (
"fmt"
"encoding/json"
)
type Student struct {
Name string `json:"name"`
Age int32 `json:"age"`
Class string `json:"class"`
}
func main() {
stu := Student {
Name: "ahaoozhang",
Age: 18,
Class: "电信1605班",
}
json, _ := json.Marshal(stu) //对stu结构体进行json编码
fmt.Println(string(json)) //打印json字符串
}
//执行的结果为:
// {"name":"ahaoozhang","age":18,"class":"电信1605班"}
可以看出在使用了jsonTag的情况下,编码后的json字符串Key与jsonTag中的内容一致。
Tag的功能并不止于此,结构体的一个成员可以有多个Tag,多个Tag之间使用空格隔开
通常一个jsonTag可以分为两部分,分别为属性名和选项,这两部分使用,隔开,属性名也就是上面所说的编/解码时替换Key的功能,通常使用的选项分别有"-"
和omitempty
-
:在编/解码时直接忽略当前属性omitempty
:在编/解码时,如果当前属性的值为空(nil),则忽略当前属性string
:在编/解码时,将对应的value转换为json的string类型
举例说明:
package main
import (
"fmt"
"encoding/json"
)
type Student struct {
Name string `json:"-"`
Age int32 `json:"age"`
Class string `json:"class"`
Ptr uintptr `json:"ptr,omitempty"`
Num int32 `json:"num,string"`
}
func main() {
stu := Student {
Name: "ahaoozhang",
Age: 18,
Class: "电信1605班",
Num: 2000,
}
json, _ := json.Marshal(stu) //对stu结构体进行json编码
fmt.Println(string(json)) //打印json字符串
}
//执行的结果为:{"age":18,"Class":"电信1605班","num":"2000"}
问题:在使用-
选项时,jsonTag必须只包含-
,才能完全忽略当前属性的编/解码
原理
使用reflect包可以获取到结构体的jsonTag,除了反射机制可以获得jsonTag以外,对于其他方式jsonTag都是不可见的。
这里主要介绍func (tag StructTag) Get(key string) string
函数,该函数可以用来获取指定key的value。
提取jsonTag
package main
import (
"fmt"
"encoding/json"
"reflect"
)
type Student struct {
Name string `json:"-" xml:"NAME"`
Age int32 `json:"age" xml:"AGE"`
Class string `json:"class"`
Ptr uintptr `json:"ptr,omitempty"`
Num int32 `json:"num,string"`
}
func main() {
stu := Student {
Name: "ahaoozhang",
Age: 18,
Class: "电信1605班",
Num: 2000,
}
stutype := reflect.TypeOf(stu)
for i := 0; i < stutype.NumField(); i++ {
field := stutype.Field(i)
fmt.Printf("json: %v; xml: %v\n", field.Tag.Get("json"), field.Tag.Get("xml"))
fmt.Printf("%v\n", )
}
}
/*结果: * json: -; xml: NAME * json: age; xml: AGE * json: ; xml: * json: num,string; xml:*/