原文链接:Go语言中构造体打Tag是什么意思?
前言
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 |
|---|---|
| xml | https://godoc.org/encoding/xml |
| json | https://godoc.org/encoding/json |
| asn1 | https://godoc.org/encoding/asn1 |
| reform | https://godoc.org/gopkg.in/re… |
| dynamodb | https://docs.aws.amazon.com/s… |
| bigquery | https://godoc.org/cloud.googl… |
| datastore | https://godoc.org/cloud.googl… |
| spanner | https://godoc.org/cloud.googl… |
| bson | https://godoc.org/labix.org/v…, https://godoc.org/go.mongodb…. |
| gorm | https://godoc.org/github.com/… |
| yaml | https://godoc.org/gopkg.in/ya… |
| toml | https://godoc.org/github.com/… |
| validate | https://github.com/go-playgro… |
| mapstructure | https://godoc.org/github.com/… |
| parser | https://godoc.org/github.com/… |
| protobuf | https://github.com/golang/pro… |
| db | https://github.com/jmoiron/sqlx |
| url | https://github.com/google/go-… |
| feature | https://github.com/nikolaydub… |
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
github
asong
欢送关注公众号:Golang梦工厂