Go语言中的StructTag类型介绍,基于Go reflect 反射实现
StructTag 是什么
在Go语言里,StructTag 是一个标记字符串,此字符串可跟随在Struct中字段定义的后面。
StructTag就是一系列的 key:"value"
形式的组合,其中key是一个不可为空的字符串,key-value组合可以有多个,空格分隔。
key
为 json
时格式:
`json:"名字,类型,omitempty"`
- 名字、类型、omitempty 都可以省略
- omitempty 如果是零值可以不序列化
陷阱
若需要序列化零值,可以将对应的类型改为指针(如 *int
、*float64
)
- Go1.16 及以后,支持 tag 合并
type User struct {
Name string `json,bson,xml,form:"name,omitempty"`
}
StructTag 的作用
StructTag 主要解决了不同类型数据集合间(Struct,Json,Table等)转换中键值Key定义不一样的问题。
- StructTag可以理解为一个不用数据类型键值Key的映射表Map,在StructTag中可以定义不用数据集合键值和Struct中Key值的映射关系,这样方便了Struct数据转为其他类型数据的过程。例如我们可以把Struct数据映射成为一个Json格式的数据,或者把Struct数据映射成为一个数据表Table。当然我们也可以依据StructTag的定义,把一个Json数据转为一个Struct结构数据。
结构体标签合并
从 go1.16 开始,支持结构体标签合并
# go1.16 之前
type MyStruct struct {
Field1 string `json:"field_1,omitempty" bson:"field_1,omitempty" xml:"field_1,omitempty" form:"field_1,omitempty" other:"value"`
}
# go1.16 及之后
type MyStruct struct {
Field1 string `json,bson,xml,form:"field_1,omitempty" other:"value"`
}
示例
Struct
和 Json
数据间的互相转换的例子:
package main
import (
"encoding/json"
"fmt"
)
type Addr struct {
Region string `json:"region"`
Street string `json:"street"`
No int `json:"no"`
}
type Person struct {
FirstName string `json:"first_name"` // FirstName <=> firest_name
LastName string `json:"last_name"`
MiddleName string `json:"middle_name,omitempty"` // `json:"-"` 也可以忽略,omitempty 当是零值时,不序列化
Age int `json:"age,string"` // 指定类型为 字符串
//isBoy bool `json:"is_boy"` // 不能是小写的,否则提示 Struct field 'isBoy' has 'json' tag but is not exported
// 命名嵌套
Addr Addr `json:"addr"`
// 匿名嵌套,和命名嵌套效果一样的
//Addr `json:"addr"`
}
func main() {
//jsonString := `{"first_name": "John", "last_name": "Smith", "age": "12"}`
jsonString := `{"first_name": "John", "middle_name":"x", "last_name": "Smith", "age": "12", "addr": {"region": "shanghai,huangpu", "street": "Street1", "no": 100}}`
person := new(Person)
err := json.Unmarshal([]byte(jsonString), person)
if err != nil {
fmt.Println(err.Error())
return
} //将json数据转为Person Struct
fmt.Println(person)
newJson, _ := json.Marshal(person) //将Person Sturct 转为json格式
fmt.Printf("%s\n", newJson)
}
// Output:
//&{John Smith x 12 {shanghai,huangpu Street1 100}}
//{"first_name":"John","last_name":"Smith","middle_name":"x","age":"12","addr":{"region":"shanghai,huangpu","street":"Street1","no":100}}