🧠 一、什么是结构体 Tag?
在 Go 中,结构体字段可以有额外的元信息,称为 Tag(标签)。这些信息通常用于:
-
序列化(如
json
,xml
,yaml
) -
表单绑定(如
form
) -
校验(如
validate
) -
数据库映射(如
gorm
,xorm
)
Tag 写在结构体字段名的后面,用 反引号 ``` 包裹。
🧱 二、结构体 Tag 的基本语法
type StructName struct { FieldName FieldType `tagKey:"tagValue"` }
💡 多个 tag 用 空格隔开,例如:
FieldName string `json:"name" xml:"name" validate:"required"`
🧩 三、图示讲解结构体 tag 组成
type User struct { ID int `json:"id"` Name string `json:"name"` Email string `json:"email,omitempty"` Age int `json:"-"` // 不序列化 }
字段名 | 类型 | Tag 字符串 | 含义 |
---|---|---|---|
ID | int | json:"id" | JSON 输出为 id |
Name | string | json:"name" | JSON 输出为 name |
string | json:"email,omitempty" | 如果为零值则不输出 | |
Age | int | json:"-" | 永远忽略,不输出 |
📦 四、实战场景演示
✅ 示例1:JSON 序列化
package main import ( "encoding/json" "fmt" ) type User struct { ID int `json:"id"` Name string `json:"name"` Email string `json:"email,omitempty"` Age int `json:"-"` } func main() { user := User{ID: 1001, Name: "李雷", Email: "", Age: 30} result, _ := json.Marshal(user) fmt.Println(string(result)) // 输出:{"id":1001,"name":"李雷"} }
🔍 为什么只有 ID 和 Name?
-
Email
为空,使用了omitempty
-
Age
被忽略,使用了"-"
✅ 示例2:GORM 中的数据库映射 tag
type Product struct { ID int `gorm:"primaryKey;autoIncrement" json:"id"` Name string `gorm:"type:varchar(100);not null" json:"name"` Price int `gorm:"column:product_price" json:"price"` }
tag 类型 | 示例内容 | 说明 |
---|---|---|
gorm | primaryKey , type , column | 表示数据库字段特性 |
json | json:"name" | 表示 JSON 序列化字段名 |
✅ 示例3:表单解析 + 校验 tag
type LoginForm struct { Username string `form:"username" json:"username" binding:"required"` Password string `form:"password" json:"password" binding:"required,min=6"` }
tag | 用法 |
---|---|
form | 表单字段绑定,例如 HTTP POST 请求 |
json | JSON 请求体解析 |
binding | 验证字段,如 required , min=6 等 |
🧪 五、如何读取 Tag?
通过反射(reflect)读取结构体字段的 tag。
import ( "fmt" "reflect" ) type Person struct { Name string `json:"name" label:"姓名"` } func main() { t := reflect.TypeOf(Person{}) field := t.Field(0) fmt.Println("json tag:", field.Tag.Get("json")) // 输出 name fmt.Println("label tag:", field.Tag.Get("label"))// 输出 姓名 }
🧠 六、tag 使用建议
建议 | 原因 |
---|---|
❗避免乱写 | tag 格式要正确,例如反引号必须成对 |
✅ 多 tag 用空格分隔 | 保持清晰易读 |
🧪 可以结合反射动态读取 tag | 做校验、自动映射等功能 |
🔐 不要暴露敏感字段到 JSON 中 | 使用 json:"-" |
🎁 七、可视化图(结构体 tag 工作流程)
+-------------------+ | struct 定义 | |-------------------| | Name string | | `json:"name"`| -----> 序列化 JSON 输出字段 "name" +-------------------+