反射操作结构体-使用Tag标签

未匹配的标注

使用Tag标签

首先,看如下这有一个练习:

Person结构体定义如下:

type Person struct {
   Name        string `label:"Person Name: " uppercase:"true"`
   Age         int    `label:"Age is: "`
   Sex         string `label:"Sex is: "`
   Description string
}

Person包含四个字段,使用一个名为lable的tag来定义打印时的标题。如果是字符串类型的字段,通过名为uppercase的tag控制是否显示字符串的大写形式(默认小写)。如:有一个Person结构体变量为:

 person{Tom 29 Male Cool}

按照上面Person中tag的使用,输出结果应该为:

Person Name: TOM
Age is: 29
Sex is: male
Description: cool

即,除 TOM 名字外,其余字段,无论输入为何,输出皆为小写。

功能实现如下:

type Person struct {
   Name        string `label:"Person Name: " uppercase:"true"`
   Age         int    `label:"Age is: "`
   Sex         string `label:"Sex is: "`
   Description string
}

// 按照tag打印结构体
func PrintUseTag(ptr interface{}) error {
   // 获取入参的类型
   reType := reflect.TypeOf(ptr)
   // 入参类型校验
   if reType.Kind() != reflect.Ptr || reType.Elem().Kind() != reflect.Struct {
      return fmt.Errorf("参数应该为结构体指针")
   }
   // 取指针指向的结构体变量
   v := reflect.ValueOf(ptr).Elem()

   // 解析字段, NumField() 4 个字段。
   for i := 0; i < v.NumField(); i++ {
      // 获取结构体字段信息
      structField := v.Type().Field(i)
      // 取tag
      tag := structField.Tag
      // 解析label tag,获取tag值
      label := tag.Get("label")
      if label == "" {
         label = structField.Name + ": "
      }
      // 解析uppercase tag, 除 uppercase 标签外,全部小写输出。
      value := fmt.Sprintf("%v", v.Field(i))

      // 字段类型为字符串时, 判断tag值是否为真,进行大小写转换。
      if structField.Type.Kind() == reflect.String {
         tagVal := tag.Get("uppercase")
         if tagVal == "true" {
            value = strings.ToUpper(value)
         } else {
            value = strings.ToLower(value)
         }
      }
      fmt.Println(label + value)
   }
   return nil
}
func main() {
   person := Person{"Tom",29,"Male","Cool"}
   PrintUseTag(&person)
}

main中初始化了一个person结构体变量,然后调用PrintUseTag函数通过反射,获取并解析tag。当字段类型为string时候,判断uppercase tag是否使用。打印每一个字段的label和value组成的字符串。Value可以是任意类型,借助于fmt包的Sprintf函数的%v,可将其他类型转化为字符串。

掌握tag的使用,我们可以使用Golang定义很多自己的工具,减少冗余代码,尤其在框架的定义中作用十分明显。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~