原文链接:
前言
asongGo
大多数初学者在看公司的项目代码时,看到的一些结构体定义会是这样的:
type Location struct {
Longitude float32 `json:"lon,omitempty"`
Latitude float32 `json:"lat,omitempty"`
}
字段后面会有一个标签,这个标签有什么用呢?
json:"lon,omitempty"jsonlonlatlonlatomitempty
看到这里,有一些朋友可能会好奇,这个你是怎么知道这样使用的呢?我可以随便写标签吗?
接下来我们就一点点来揭秘,开车!!!
什么是标签
Gojson/xmlormencoding/json
`key1:"value1" key2:"value2" key3:"value3"...` // 键值对用空格分隔
结构体标签可以有多个键值对,键与值要用冒号分隔,值要使用双引号括起来,多个键值对之间要使用一个空格分隔,千万不要使用逗号!!!
encoding/json
`json:"lon,omitempty"`
gorm
`gorm:"column:id;primaryKey"
具体使用什么符号分隔需要大家要看各自库的文档获取。
结构体标签是在编译阶段就和成员进行关联的,以字符串的形式进行关联,在运行阶段可以通过反射读取出来。
go vet
type User struct {
Name string `abc def ghk`
Age uint16 `123: 232`
}
func main() {
}
go vet main.go
# command-line-arguments
go_vet_tag/main.go:4:2: struct field tag `abc def ghk` not compatible with reflect.StructTag.Get: bad syntax for struct tag pair
go_vet_tag/main.go:5:2: struct field tag `123: 232` not compatible with reflect.StructTag.Get: bad syntax for struct tag value
bad syntax for struct tag pairbad syntax for struct tag value
go vetCI
标签使用场景
Gostruct tag
Tag | Documentation |
---|
jsonyamlgormvalidatemapstructureprotobufginvalidatevalidate
具体这些库中是怎么使用的,大家可以看官方文档介绍,写的都很详细,具体场景具体使用哈!!!
自定义结构体标签
现在我们可以回答开头的一个问题了,结构体标签是可以随意写的,只要符合语法规则,任意写都可以的,但是一些库没有支持该标签的情况下,随意写的标签是没有任何意义的,如果想要我们的标签变得有意义,就需要我们提供解析方法。可以通过反射的方式获取标签,所以我们就来看一个例子,如何使用反射获取到自定义的结构体标签。
type User struct {
Name string `asong:"Username"`
Age uint16 `asong:"age"`
Password string `asong:"min=6,max=10"`
}
func getTag(u User) {
t := reflect.TypeOf(u)
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
tag := field.Tag.Get("asong")
fmt.Println("get tag is ", tag)
}
}
func main() {
u := User{
Name: "asong",
Age: 5,
Password: "123456",
}
getTag(u)
}
运行结果如下:
get tag is Username
get tag is age
get tag is min=6,max=10
TypeOfStructFieldTag
// A StructField describes a single field in a struct.
type StructField struct {
Name string
PkgPath string
Type Type // field type
Tag StructTag // field tag string
Offset uintptr // offset within struct, in bytes
Index []int // index sequence for Type.FieldByIndex
Anonymous bool // is an embedded field
}
TagGetLoopup
func (tag StructTag) Get(key string) string
func (tag StructTag) Lookup(key string) (value string, ok bool)
GetLookupLookupkeyGet
总结
Govalidaetag
asong
欢迎关注公众号:Golang梦工厂