go语言中结构体tag使用

go中的tag在结构体中使用的。有两个作用:

(1)给结构体属性起别名,字段映射。对于不同类型的类型对应不同的值,比如xml,yaml,json等分别对应着不同的区域,当然标签也不同。比如json,bson,都是约定俗成的了。

(2)做属性判断和验证。

1.tag中的格式

(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等,当然这个标签是可以自定义的

go语言中结构体tag使用_第1张图片

2.json,bson标签

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  包或其他第三方包进行解析和处理。

3.举例

其实自己也可以想例子,以下案例作参考。

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

你可能感兴趣的:(【Go】,golang)