Go语言tag结构体标签的用法
Go语言在定义结构体的时候,还可以为每个成员添加标签 tag,它是一个附属于成员的字符串,代表文档或其他的重要标记。
比如说,解析 JSON 需要使用内置包 encoding/json,该包为我们提供了一些默认标签;还有一些开源的 ORM 框架,也广泛使用结构体的标签 tag。
结构体标签设置说明如下:
结构体标签语法格式如下:
如果将结构体的每个成员首个字母改为大写格式,内置包 encoding/json 的 Marshal() 能将结构体转换为 JSON 数据,但是 JSON 数据的键(key)一般以小写格式表示,为了使数据转换成功且转换结果符合格式要求,这时候需要使用结构体标签 tag 实现,实现代码如下:
运行上述代码,运行结果为:
比如说,解析 JSON 需要使用内置包 encoding/json,该包为我们提供了一些默认标签;还有一些开源的 ORM 框架,也广泛使用结构体的标签 tag。
结构体标签设置说明如下:
- 标签在成员的数据类型后面设置,以字符串形式表示,并且使用反引号表示字符串;
- 标签内容格式由一个或多个键值对组成,键与值使用冒号分隔,并且不能留有空格,值用双引号引起来,多个键值对之间使用一个空格分隔。
结构体标签语法格式如下:
type name struct { field1 dataType `key1:"value1" key2:"value2"` field2 dataType `key1:"value1" key2:"value2"` ... }结构体标签看似仅是一个注释说明,但在开发中十分重要,比如将结构体转为 JSON 数据,我们需要借助内置包 encoding/json 实现,代码如下:
package main import ( "encoding/json" "fmt" ) type Student struct { name string age int score int } func main() { var stu Student = Student{ name: "张三", age: 22, score: 88, } data, _ := json.Marshal(stu) fmt.Printf("结构体转换JSON:%v\n", string(data)) }上述示例首先定义结构体 Student,然后在主函数 main() 中实例化结构体 Student 并为每个成员赋予初始值,最后调用内置包 encoding/json 的 Marshal() 方法将结构体转换为JSON数据,运行结果为:
结构体转换JSON:{}
从运行结果看到,程序并没有将结构体的数据转换为 JSON 数据,因为结构体的每个成员的首个字母是小写格式的,所以结构体的成员不是导出标识符,内置包 encoding/json 无法成功获取结构体每个成员的数据。如果将结构体的每个成员首个字母改为大写格式,内置包 encoding/json 的 Marshal() 能将结构体转换为 JSON 数据,但是 JSON 数据的键(key)一般以小写格式表示,为了使数据转换成功且转换结果符合格式要求,这时候需要使用结构体标签 tag 实现,实现代码如下:
package main import ( "encoding/json" "fmt" ) type Student struct { // `json:"name"`表示JSON序列化时,结构体成员展示形式为name Name string `'json:"name"` Age int `json:"age"` Score int `json:"score"` } func main() { var stu Student = Student{ Name: "张三", Age: 22, Score: 88, } data, _ := json.Marshal(stu) fmt.Println(string(data)) }从示例看到,结构体转换 JSON 的过程如下:
- 每个结构体成员设置了标签 tag,格式为`json:"xxx"`,不同模块或包对结构体标签的内容格式各有不同。
- 在主函数 main() 中实例化结构体,为每个结构体成员赋予具体数值。
- 结构体成员首个字母是大写格式,能作为导出标识符而被内置包 encoding/json 的 Marshal() 获取。
- 通过反射机制从结构体成员获取标签,将标签内容作为 JSON 的键(key),成员值作为 JSON 的值(value)。
运行上述代码,运行结果为:
{"name":"张三","age":22,"score":88}