聊一聊Go语言中结构体标签(Struct Tag)

1,953 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第30天,点击查看活动详情

前言

结构体在go语言中的应用非常广范,结构体在定义的时候除了字段和类型之外,还可以有一个可选的标签tag,它是一个附属于字段的字符串,可以是文档或其他的重要标记,Golang的结构体标签开发中也用的非常多,尤其是在json处理的地方用,今天与大家分享Go语言中结构体标签是怎么使用的, 感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

结构体标签

struct结构体中在成员变量后面使用""``定义一些描述性信息,这就叫tag,也就是标签。我们可以通过 reflect.Type获取结构体成员信息 reflect.StructField结构中的 tag

结构体标签的格式

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

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

  • key: 必须是非空字符串,字符串不能包含控制字符、空格、引号、冒号。
  • value: 以双引号标记的字符串:

结构体标签由一个或多个键值对组成,键值对使用冒号:分隔,值使用双引号括起来,键值对之间使用一个空格分隔,千万不要使用逗号!

如果我们想在一个值中传递多个信息怎么办?不同的库中实现的是不一样的,在encoding/json中,多值使用逗号分隔;在gorm中,多值使用分号分隔。示例如下:

type User struct {
    Id int `json:"id" gorm:"column:id;primaryKey"`
    Name string `json:"name"`
    Password string `json:"password,omitempty"`
}

Tag可选的字段

  • “-”:表示不需要解析这个字段
  • “omitempty”:当字段为空(默认值)时,不要解析这个字段;比如是false、0、nil或者长度为0的array、map、slice、string等。
  • FieldName:当解析json、xml、ini等的时候用这个名字。

获取Tag

可以使用反射包(reflect)中的方法来获取,StructTag提供了Get(key string) string 方法来获取Tag;

package main

import (
    "reflect"
    "fmt"
)

type User struct {
    Name string `json:"name" xml:"name"`
    Age   string `json:"age"`
}

func main() {
    s := User{}
    st := reflect.TypeOf(s)

    field1 := st.Field(0)
    fmt.Printf("json:%v\n", field1.Tag.Get("json"))
    fmt.Printf("xml:%v\n", field1.Tag.Get("xml"))

    filed2 := st.Field(1)
    fmt.Printf("json:%v\n", filed2.Tag.Get("json"))
}

程序输出如下:

json:name

xml:name

json:age

小结

使用反射可以动态的给结构体成员赋值,正是因为有tag,在赋值前可以使用tag来决定赋值的动作。常见的tag用法,主要是JSON数据解析、ORM映射等都会用到结构体标签。