结构体Tag使用

* 本页面总结凯冰音乐APP项目结构体Tag使用的相关内容。

之所以把这个单拎出来要总结一下,主要是这几天写后台接口,确实是写了太多的Struct Tag,你就会感觉,好像Go的项目就是在写结构体,然后写Tag,然后写结构体方法,无限循环。

关于结构体和结构体Tag,在 《Go编程语言》 手册的 结构体struct 章节里是有过总结的。今天单独针对Tag再做一个详细的,亲手写过之后的体验和感受。

何为结构体Tag

结构体标签是对结构体字段的额外信息标签

JSON、BSON 等格式进行序列化及对象关系映射(Object Relational Mapping,简称 ORM)系统都会用到结构体标签,这些系统使用标签设定字段在处理时应该具备的特殊属性和可能发生的行为。这些信息都是静态的,无须实例化结构体,可以通过反射获取到

Tag 在结构体字段后方书写的格式如下:

  `key1:"value1" key2:"value2"`

结构体标签由一个或多个键值对组成;键与值使用冒号分隔,值用双引号括起来;键值对之间使用一个空格分隔。因为结构体标签的解析代码的容错能力很差,所以一定要严格遵照规则来书写,否则格式出错,编译和运行时都不会提示任何错误,进而无法得到你预期的结果。

以我项目中的歌曲列表ShowSongList的结构体格式如下:

  type ShowSongList struct {
    SongId int `gorm:"column:id" json:"-"`
    SongHash string `json:"song_hash"`
    MusicTitle string `gorm:"column:music_title" json:"music_title"`
    SingerId int `gorm:"column:singer_id" json:"singer_id"`
    SingerName string `gorm:"column:singer_name" json:"singer_name"`
    SingerHead string `gorm:"column:singer_head" json:"singer_head"`
    SourceIcon string `json:"source_icon"`
    SourceName string `json:"source_name"`
    SourceDesc string `json:"source_desc"`
    MusicUrl string `gorm:"column:music_url" json:"music_url"`
    ListenCounts int `gorm:"column:listen_counts" json:"listen_counts"`
  }

上面的json就代表解析json数据时对应的字段,gorm代表Gorm查询数据时对应的数据表字段。其中 json:"-" 标识json序列化/反序列化时忽略掉该字段

  // json数据解析和绑定
  type Login struct {
    User string `form:"username" json:"user" uri:"user" xml:"user" binding:"required"`
    Password string `form:"password" json:"password" uri:"password" xml:"password" binding:"required"`
    Email string `json:"email,omitempty"` //注意email,omitempty整体作为json tag的值
    UID int64 `json:"id,string"` //添加string tag
  }

这个例子里,xml:是针对xml解析包使用时的字段名,form:gin包中用于参数绑定(.shouldbind())时的字段名,binding :“required”,是必须要解析,若接收值为空,则报错。`json:"email,omitempty"`, 标识解析时如果该字段是空值忽略该字段(因为默认情况下, 当 struct 中的字段没有值时, json.Marshal() 序列化的时候不会忽略这些字段,而是默认输出字段的类型零值)。 `json:"id,string"`用来优雅处理字符串格式的数字,前端在传递来的json数据中可能会使用字符串类型的数字,这个时候可以在结构体tag中添加string来告诉json包从字符串中解析相应字段的数据。

还有更多中写法,特定场景特定分析和使用即可。

结构体Tag本身也有方法

StructTag 拥有一些方法,可以进行 Tag 信息的解析和提取:

  • func(tag StructTag)Get(key string)string : 得到某个key的值
  • func(tag StructTag)Lookup(key string)(value string,ok bool):根据 Tag 中的键,查询值是否存在
  type cat struct {
      Name string
      Type int `json:"type" id:"100"`
  }
  typeOfCat := reflect.TypeOf(cat{})
  if catType, ok := typeOfCat.FieldByName("Type"); ok {
      fmt.Println(catType.Tag.Get("json"))
  }

结构体Tag的知识就总结到这里吧,以后接触更多的再更新,你都学会(废)了吗?


* 本页内容参考以下数据源:

  • https://doc.zkbhj.com/golang/3-complex-struct.html
  • http://c.biancheng.net/view/112.html
  • https://blog.csdn.net/csdniter/article/details/103869872

凯冰科技 · 代码改变世界,技术改变生活
下一篇:Gorm操作数据库 →