go中的tag在结构体中使用的。有两个作用:
(1)给结构体属性起别名,字段映射。对于不同类型的类型对应不同的值,比如xml,yaml,json等分别对应着不同的区域,当然标签也不同。比如json,bson,都是约定俗成的了。
(2)做属性判断和验证。
(1)tag本身是一个字符串,字符串整个使用反引号``。
(2)key必须是非空字符串,不能使用双引号。字符串不能包含控制字符,空格,引号,冒号。
(3)value以双引号标记的字符串。
(4)多个标签之间使用空格连接,标签名不需要使用双引号,标签名对应的值需要使用双引号,多个标签值需要使用逗号连接。
举例:
type User struct {
UserId int `json:"user_id" bson:"b_user_id,bson_id"`
UserName string `json:"user_name" bson:"b_user_name"`
}
注意:冒号前后不能有空格。
比如以下几个就是约定俗成的标签:bson,json,yaml,xml等,当然这个标签是可以自定义的
type User struct {
ID string `json:"id,omitempty" bson:"_id,omitempty"`
Username string `json:"username,omitempty" bson:"username,omitempty"`
Email string `json:"email,omitempty" bson:"email,omitempty"`
}
比如以上代码,标签是为了起别名,只是每个标签作用的地方不一样。比如json前后端交互的时候用的多,比如请求和响应的都是json格式的数据。bson在和mongoDB数据库交互的时候使用的多。
json标签:使用了json标签,用于指定字段在json编码中的名称和行为,在与前端进行数据交互时,使用json标签可以确保字段在序列化为 JSON 数据时具有正确的名称和行为。
bson标签:使用了bson标签,bson标签是用于指定字段在 MongoDB 数据库中的名称和行为。当使用 MongoDB 数据库进行数据存储时,使用 bson标签可以确保字段在序列化和反序列化 BSON(Binary JSON)数据时具有正确的名称和行为。
通过这些标签为字段起别名,可以在前端和数据库端建立字段映射,确保数据正确的传递和存储。
1. JSON 标签( json ):
- 在结构体字段上使用 json:"field_name" 标签,可以指定字段在 JSON 编码和解码中的别名和选项。
- 例如: UserName string json:"user_name"
- 这样的标签可以指定在 JSON 编码和解码中使用 "user_name" 作为字段的别名。
2. BSON 标签( bson ):
- 在结构体字段上使用 bson:"field_name" 标签,可以指定字段在 BSON 编码和解码中的别名和选项。
- 例如: UserName string bson:"b_user_name"
- 这样的标签可以指定在 BSON 编码和解码中使用 "b_user_name" 作为字段的别名。
3. YAML 标签( yaml ):
- 在结构体字段上使用 yaml:"field_name" 标签,可以指定字段在 YAML 编码和解码中的别名和选项。
- 例如: UserName string yaml:"user_name"
- 这样的标签可以指定在 YAML 编码和解码中使用 "user_name" 作为字段的别名。
4. XML 标签( xml ):
- 在结构体字段上使用 xml:"field_name" 标签,可以指定字段在 XML 编码和解码中的别名和选项。
- 例如: UserName string xml:"user_name"
- 这样的标签可以指定在 XML 编码和解码中使用 "user_name" 作为字段的别名。
需要注意的是,这些标签的具体含义和使用方式可能因使用的库或工具而有所不同。这些示例展示了在 Go 语言中使用不同标签的一般用法,但具体的实现可能会因库或工具的不同而有所区别。
至于 YAML 和 XML 文件的读取,可以使用相应的库进行解析和处理。对于 YAML 文件,可以使用 gopkg.in/yaml.v2 包,对于 XML 文件,可以使用 encoding/xml 包或其他第三方包进行解析和处理。
其实自己也可以想例子,以下案例作参考。
type Student struct {
// 返回给前端的话,首字母大写很奇怪,所以给Name起了个别名
Name string `json:"name"`
Age int
}
func testTag() {
s1 := Student{
Name: "s1k",
}
bytes, err := json.Marshal(s1)
if err != nil {
panic(err)
}
// 将[]byte数组转换为string类型json类型
//s := string(bytes)
var s Student
json.Unmarshal(bytes, &s)
fmt.Printf("%v", s)
}
type User struct {
UserId int `json:"user_id" bson:"b_user_id"`
UserName string `json:"user_name" bson:"b_user_name"`
}
func testJson() {
u := &User{
UserId: 1,
UserName: "tony",
}
fmt.Printf("%T", u)
bytes, _ := json.Marshal(u)
fmt.Println(string(bytes))
// 通过反射获取标签的值
// reflect.TypeOf(u),获取的是指针类型
types := reflect.TypeOf(u)
field := types.Elem().Field(0)
fmt.Println(field.Tag.Get("json"))
fmt.Println(field.Tag.Get("bson"))
}
type Http struct {
Port string `yaml:"port"`
Secret string `yaml:"secretKey"`
Domain string `yaml:"domain"`
}
type Config struct {
Http `yaml:"http"`
}
func testYaml() {
//var h Http
config := new(Config)
file, err := ioutil.ReadFile("config.yaml")
if err != nil {
fmt.Println(err.Error())
}
// 将解析后的数据存储到结构体中
err = yaml.Unmarshal(file, config)
if err != nil {
fmt.Println(err.Error())
}
fmt.Println(config.Http, " ", config.Port, " ", config.Secret, " ", config.Domain)
}
type Person struct {
Name string `json:"name"`
Age string `json:"age,omitempty"` //有 omitempty 属性,因此 encoding/json 在将对象转化 json 字符串时,
// 只要发现对象里的 Addr 为 false, 0, 空指针,空接口,空数组,空切片,空映射,空字符串中的一种,就会被忽略。
}
func testTags() {
p1 := &Person{
Name: "zhangsan",
}
// 所以空字符串就会被忽略
bytes, _ := json.Marshal(p1)
fmt.Printf("%s", bytes)
fmt.Println(p1)
fmt.Printf("%T", p1)
p2 := &Person{
Name: "lisi",
Age: "15",
}
fmt.Println(p2)
}
// 从结构体中取出tag,通过反射
/*
获取字段 field
获取标签 tag
获取键值对 key:value
// 三种获取 field
field := reflect.TypeOf(obj).FieldByName("Name")
field := reflect.ValueOf(obj).Type().Field(i) // i 表示第几个字段
field := reflect.ValueOf(&obj).Elem().Type().Field(i) // i 表示第几个字段
// 获取 Tag
tag := field.Tag
// 获取键值对
labelValue := tag.Get("label")
labelValue,ok := tag.Lookup("label")
*/
func getTag() {
p2 := &Person{
Name: "lisi",
Age: "15",
}
// 三种方式获取Field
field := reflect.ValueOf(p2).Elem().Type().Field(1)
getName := field.Tag.Get("json")
// 获取tag
//value, ok := tag.Lookup("name")
fmt.Println(getName)
}