结构体的tag是Golang区别于PHP独有的概念,本文会详细介绍Go中tag的定义、用法及常用场景
本文概要
- 结构体
tag
的定义 - 结构体
tag
的读取 - 结构体
tag
的常用场景
结构体 tag
的定义
在Go语言中,结构体标签是通过在结构体定义的字段后面添加一个字符串来定义的。这个字符串被称为标签(tag),其中包含了一些键-值对,以键:值
的形式表示。例如:
type Person struct {
Name string `json:"name" xml:"name" csv:"name"`
Age int `json:"age" xml:"age" csv:"age"`
Address string `json:"address" xml:"address" csv:"address"`
}
如何读取结构体 tag
tag的读取利用的是golagn的反射机制
package main
import (
"fmt"
"reflect"
)
type Person struct {
Name string `json:"name" xml:"person_name"`
Age int `json:"age" xml:"person_age"`
}
func main() {
p := Person{Name: "John Doe", Age: 30}
// 获取结构体的反射类型
t := reflect.TypeOf(p)
// 遍历结构体的字段
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
tag := field.Tag.Get("json") // 获取json标签
fmt.Printf("Field: %s, Tag: %s\n", field.Name, tag)
}
}
// Output:
Field: Name, Tag: name
Field: Age, Tag: age
结构体 tag
的常用场景
比如上面的tag中包含的json tag,当使用json.Marshal时,会读取对应字段定义的json tag,然后将json对象中的key赋值为该值。
需要特别注意,对于以小写开头的字段,序列化及反序列化时是忽略的;另外对于即使没定义json tag的字段序列化时通常也会默认以字段名赋值到json的键名上
这个是非常常见的需求,比如前端传过来的参数都需要校验下;这个验证比较常用的库就是 go-playground/validator,只需要在结构体tag上完成验证规则标记,即可快速书进行验证
type User struct {
Name string `validate:"required"`
Age int `validate:"min=1,max=120"`
Email string `validate:"required,email"`
Password string `validate:"required,min=6"`
}
常用的数据库,比如gorm
or xorm
均是利用tag完成数据字段的对应
// Gorm
type User struct {
Name string `gorm:"column:username"`
Age int `gorm:"column:age"`
Email string `gorm:"column:email"`
}
// Xorm
type User struct {
Name string `xorm:"'username'"`
Age int `xorm:"'age'"`
Email string `xorm:"'email'"`
}
tag 的用处自然不止这么点,利用tag可以完成更多的程序的自动化,比如标记某个字段是否记录日志等等,tag也可以完全自定义用途