Go 语言常用的结构体标签解析
在 Go 语言中,结构体标签(Struct Tags) 是用于在结构体字段上附加元数据的字符串,通常用于 JSON 序列化、数据库 ORM 绑定、表单验证等 场景。结构体标签的本质是 反射(Reflection),可以通过 reflect
包进行解析。
1. 结构体标签的基本语法
结构体标签通常以 反引号(`) 包围,格式如下:
type StructName struct {
FieldName FieldType `tag_key:"tag_value"`
}
多个标签可以在同一行中使用 空格 分隔:
type User struct {
ID int `json:"id" xml:"id"`
Name string `json:"name" xml:"name" validate:"required"`
}
2. Go 语言常见的结构体标签
标签 | 作用 | 示例 |
---|---|---|
json | JSON 编解码 | json:"user_id" |
xml | XML 解析 | xml:"user_id" |
gorm | ORM 数据库映射 | gorm:"column:user_id;primaryKey" |
validate | 数据校验 | validate:"required,email" |
form | Web 表单绑定 | form:"username" |
binding | Gin 参数校验 | binding:"required" |
yaml | YAML 解析 | yaml:"config_name" |
3. json
结构体标签(JSON 编解码)
json
标签用于 Go 结构体与 JSON 之间的转换,通常用于 API 数据交互。
(1)基本用法
package main
import (
"encoding/json"
"fmt"
)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
user := User{ID: 1, Name: "Alice", Age: 25}
// 结构体转 JSON
jsonData, _ := json.Marshal(user)
fmt.Println(string(jsonData)) // {"id":1,"name":"Alice","age":25}
// JSON 转结构体
jsonStr := `{"id":2,"name":"Bob","age":30}`
var newUser User
json.Unmarshal([]byte(jsonStr), &newUser)
fmt.Println(newUser) // {2 Bob 30}
}
2)忽略字段
json:"-"
:表示 序列化和反序列化时忽略该字段json:",omitempty"
:如果字段值是 零值(0, "" , nil
),则 不包含在 JSON 结果中
type User struct {
Password string `json:"-"` // 忽略此字段
Email string `json:"email,omitempty"` // 若为空,则不序列化
}
4. gorm
结构体标签(数据库 ORM 映射)
gorm
标签用于 数据库表字段映射,通常在 GORM
ORM 框架中使用。
(1)基本用法
type User struct {
ID uint `gorm:"primaryKey"`
Name string `gorm:"column:user_name;type:varchar(100);not null"`
Age int `gorm:"default:18"`
CreatedAt int64 `gorm:"autoCreateTime"`
}
(2)常见 gorm
标签
标签 | 作用 |
---|---|
primaryKey | 设为主键 |
column:name | 指定数据库字段名 |
type:varchar(100) | 指定字段类型 |
not null | 不能为空 |
default:18 | 设置默认值 |
autoCreateTime | 自动填充创建时间 |
5. validate
结构体标签(数据校验)
validate
标签用于 请求参数校验,主要配合 github.com/go-playground/validator/v10
库使用。
(1)安装依赖
go get github.com/go-playground/validator/v10
(2)示例
package main
import (
"fmt"
"github.com/go-playground/validator/v10"
)
type User struct {
Name string `validate:"required"` // 必填
Email string `validate:"required,email"` // 必填且格式为 Email
Age int `validate:"gte=18,lte=60"` // 年龄必须在 18-60 之间
}
func main() {
validate := validator.New()
user := User{Name: "Alice", Email: "alice@example.com", Age: 20}
err := validate.Struct(user)
if err != nil {
fmt.Println("校验失败:", err)
} else {
fmt.Println("校验通过!")
}
}
3)常见 validate
规则
规则 | 作用 |
---|---|
required | 必填 |
email | 必须是邮箱格式 |
gte=18 | 必须 >=18 |
lte=60 | 必须 <=60 |
oneof=admin user guest | 只能是 admin/user/guest |
6. binding
结构体标签(Gin 参数校验)
在 Gin
框架中,binding
标签用于 自动校验请求参数。
示例
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
type RegisterRequest struct {
Username string `json:"username" binding:"required,min=3,max=20"`
Email string `json:"email" binding:"required,email"`
}
func RegisterHandler(c *gin.Context) {
var req RegisterRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "注册成功"})
}
func main() {
r := gin.Default()
r.POST("/register", RegisterHandler)
r.Run(":8080")
}
7. form
结构体标签(表单解析)
form
标签用于解析 HTML 表单提交的数据。
示例
type LoginForm struct {
Username string `form:"username"`
Password string `form:"password"`
}
在 Gin 处理 POST
表单:
func LoginHandler(c *gin.Context) {
var form LoginForm
if err := c.ShouldBind(&form); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
c.JSON(200, gin.H{"message": "登录成功"})
}
8. yaml
结构体标签(YAML 配置解析)
yaml
标签用于 解析 YAML 配置文件,一般用于 读取应用配置。
示例
package main
import (
"fmt"
"gopkg.in/yaml.v3"
)
type Config struct {
ServerPort int `yaml:"server_port"`
DbHost string `yaml:"db_host"`
}
func main() {
yamlData := `
server_port: 8080
db_host: "localhost"
`
var config Config
yaml.Unmarshal([]byte(yamlData), &config)
fmt.Println(config) // {8080 localhost}
}
总结
标签 | 用途 |
---|---|
json | JSON 解析 |
xml | XML 解析 |
gorm | ORM 数据库映射 |
validate | 数据校验 |
binding | Gin 参数校验 |
form | 表单解析 |
yaml | YAML 配置解析 |
📌 结构体标签广泛用于数据序列化、数据库操作、参数校验等场景,是 Go 语言开发中的重要组成部分! 🚀