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)
- }