Go语言结构体标签(Tag)详解(附带实例)
在一般情况下,Go 语言定义的结构体中,每个字段都是由字段名称和字段类型构成的。
例如,在定义的 Book 类型的结构体中,包含两个字段:
代码如下:
结构体标签是一系列用空格分隔的键值对序列,用英文格式下的反引号(即``)括起来。结构体标签的语法格式如下:
下面为上面定义的 Book 类型的结构体中的两个字段增加标签。代码如下:
下面通过示例演示如何使用为字段增加标签的结构体编码 JSON。代码如下:
Go 语言支持 3 种获取结构体标签的方式,分别是获取字段信息、获取结构体标签和获取键值对。
下面演示如何获取结构体标签和键值对。代码如下:
为了深入探究结构体成员的信息,要理解 Go 语言提供的结构体成员的语法格式,即:
例如,在定义的 Book 类型的结构体中,包含两个字段:
- 一个字段是表示图书名称的 string 类型 BookName;
- 另一个字段是表示图书价格的 float64 类型 BookPrice。
代码如下:
type Book struct { //定义的 Book 类型的结构体 BookName string //表示图书名称的 string 类型 BookName BookPrice float64 //表示图书价格的 float64 类型 BookPrice }
结构体标签的使用
除了字段名称和字段类型,还可以为每个字段增加一个属性,即“结构体标签(Tag)”。结构体标签是一系列用空格分隔的键值对序列,用英文格式下的反引号(即``)括起来。结构体标签的语法格式如下:
`key:"value" key2:"value2" key3:"value3"`结构体标签由一个或多个键值对组成。键与值使用冒号分隔,值用双引号括起来。键值对之间使用一个空格分隔。
下面为上面定义的 Book 类型的结构体中的两个字段增加标签。代码如下:
type Book struct { BookName string `json:"BookName"` bookPrice float64 `json:"bookPrice"` }当键为 json 时,这个键对应的值不仅能控制 encoding/json 包的编码和解码的行为,还能控制 encoding 下的其他包的编码和解码的行为。
下面通过示例演示如何使用为字段增加标签的结构体编码 JSON。代码如下:
package main import ( "encoding/json" "fmt" ) type Book struct { BookName string `json:"name"` BookPrice float64 `json:"price"` } func main() { book := Book{ BookName: "C语言入门教程", BookPrice: 49.90, } res, := json.Marshal(book) //结构体转为 JSON fmt.Printf("res:%s\n", res) //打印 JSON }运行结果如下:
res:{"name":"C语言入门教程","price":49.4}
Go语言结构体标签的获取
在开发过程中,如何获取结构体标签呢?使用反射是关键。Go 语言支持 3 种获取结构体标签的方式,分别是获取字段信息、获取结构体标签和获取键值对。
1) 获取字段信息
Go语言同样有 3 种获取字段信息的方式。这 3 种方式的语法格式如下:field := reflect.TypeOf(obj).FieldByName("Name") //表示第几个字段 field := reflect.ValueOf(obj).Type().Field(i) //表示第几个字段 field := reflect.ValueOf(&obj).Elem().Type().Field(i) //表示第几个字段
2) 获取结构体标签
Go 语言获取结构体标签的语法格式如下:tag := field.Tag
3) 获取键值对
Go 语言有两种获取键值对的方式,语法格式如下:labelValue:= tag.Get("label") //当没有获取到对应的结构体标签时,Get()函数返回空字符串 labelValue, ok := tag.Lookup("label")
下面演示如何获取结构体标签和键值对。代码如下:
package main import ( "fmt" "reflect" ) type Book struct { BookName string `json:"name"` BookPrice float64 `json:"price"` } func main() { book := reflect.TypeOf(Book{}) //创建结构体 Book{}的反射对象 nm, _ := book.FieldByName("BookName") //获取字段 BookName 的信息 fmt.Println("字段 BookName 的信息:\n", nm) //获取字段 BookName 对应的结构体标签 tag := nm.Tag //获取与字段 BookName 对应的结构体标签 fmt.Println("与字段 BookName 对应的结构体标签:\n", tag) value, _ = tag.Lookup("json") //获取与字段 BookName 对应的结构体标签中的键值对 fmt.Println("与字段 BookName 对应的结构体标签中的键值对:\n key: json, value:", value) }运行结果如下:
字段 BookName 的信息: (BookName string json:"name" 0 [0] false) 与字段 BookName 对应的结构体标签: json:"name" 与字段 BookName 对应的结构体标签中的键值对: key: json, value: name在上述运行结果中,字段 BookName 的信息比较复杂。字段 BookName 的信息表示的是字段 BookName 与结构体 Book{} 的关系,如偏移、索引、是否为匿名字段、结构体标签等。
为了深入探究结构体成员的信息,要理解 Go 语言提供的结构体成员的语法格式,即:
type StructField struct { Name string //字段名 PkgPath string //字段在结构体中的路径 Type Type //字段的反射类型对象 Tag StructTag //字段的结构体标签 Offset uintptr //字段在结构体中的相对偏移 Index []int //字段对应的索引值 Anonymous bool //是否为匿名字段 }