Go 语言中的 Struct Tag 的用法详解

[复制链接]
发表于 2025-5-23 22:16:52 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
在 Go 语言中,布局体字段标签(Struct Tag) 是一种用于给字段添加元信息(metadata)的机制,常用于序列化(如 JSON、XML)、ORM 映射、验证等场景。你在开发 Web 应用或处理数据交互时,一定会经常看到类似下面的写法:
  1. type User struct {
  2.         Username string `json:"username"`
  3.         Token    string `json:"token"`
  4. }
复制代码
此中的 json:"token" 就是字段标签,它并不影响 Go 语言本身的语法逻辑,但它在使用反射(reflect)时非常有用,特别是当你用尺度库如 encoding/json 时。
一、布局体标签的基本语法

布局体标签是一对反引号 ` 包起来的字符串,里面是一个键值对的形式:
  1. FieldName FieldType `key:"value"`
  2. //可以写多个键值对:
  3. FieldName FieldType `json:"token" xml:"token" validate:"required"`
复制代码
这些标签是给其他包(通常是库)解析使用的,不影响 Go 编译器的行为。
二、json:"token"的详细含义

当你用 encoding/json 包将布局体编码为 JSON 时,这个标签的作用是:
指定序列化后的字段名
默认环境下,Go 会使用布局体字段名作为 JSON 的字段名。但留意:
Go 布局体的字段是大写开头(导出);
JSON 通常用小写字段名(如 “token”);
为了统一后端返回格式并满足前端规范,我们可以显式指定字段名:
  1. type User struct {
  2.         Token string `json:"token"`
  3. }
复制代码
生成的json:
  1. {
  2.   "token": "abc123"
  3. }
复制代码
反序列化时也生效
当你将 JSON 反序列化成布局体时,Go 会根据标签来找对应字段。例如上面的json格式能乐成映射到:
  1. var user User
  2. json.Unmarshal(data, &user)
  3. // user.Token == "abc123"
复制代码
三、常见的标签格式变体

  1. type User struct {
  2.         Token string `json:"token"`           // 显式指定字段名为 token
  3.         Age   int    `json:"-"`               // 忽略该字段,不进行序列化
  4.         Email string `json:"email,omitempty"` // 若为空则忽略该字段
  5. }
复制代码
json:“-”: 表示这个字段永远不会被编码或解码,即不导出。
json:“email,omitempty”: 表示只有字段不为默认值时,才会被编码到 JSON(好比字符串为 “”,数字为 0 就会忽略)。
四、使用示例

  1. package main
  2. import (
  3.         "encoding/json"
  4.         "fmt"
  5. )
  6. type User struct {
  7.         Username string `json:"username"`
  8.         Token    string `json:"token"`
  9.         Age      int    `json:"-"` // 不导出
  10. }
  11. func main() {
  12.         user := User{
  13.                 Username: "Alice",
  14.                 Token:    "abc123",
  15.                 Age:      30,
  16.         }
  17.         data, _ := json.Marshal(user)
  18.         fmt.Println(string(data))
  19. }
  20. //{"username":"Alice","token":"abc123"}
复制代码
五、使用建议


  • 字段必须导出(首字母大写),否则即使有 tag,json 包也不会访问它。
  • 保举统一使用小写 JSON 字段名:json:“username”,更符合前端 JSON 风格。
  • 如有嵌套布局体,留意为子布局体也添加 json 标签。!!!~~~~~~~~!!! 务必都为添加 json 标签的布局体!!!!不然前端解析不了!!!
疑问? 如果json tag为"-" ,为什么不把布局体首字母小写呢 不是一个效果吗?

✅json:"-"的用途
json:“-” 是明白告诉 encoding/json:“这个字段你不要处理,序列化/反序列化时忽略它”。这在布局体对外袒露字段但不希望被 JSON 处理时非常有用,好比:
  1. type User struct {
  2.         Username string `json:"username"`
  3.         Password string `json:"-"` // 不想被输出!
  4. }
复制代码
你仍旧可以在后端处理 Password 字段,但它不会出现在 JSON 输出中。这是安全和布局清晰性方面的明白表达。
总结:选择建议
目的用法保举字段仅用于内部逻辑,不想暴袒露去小写字段字段对步伐可见,但不想在 JSON 中出现json:"-"需要 JSON 中出现但字段名差别json:"your_name"希望字段在为空时不出现json:"your_name,omitempty" 简单例子:

  1. type RespMsg struct {
  2.         Code int         `json:"code"`
  3.         Msg  string      `json:"msg"`
  4.         Data interface{} `json:"data"`
  5. }
  6. type LoginData struct {
  7.         Token    string `json:"token"`
  8.         Username string `json:"username"`
  9.         Location string `json:"location"`
  10. }
  11. rsp := RespMsg{
  12.         Code: 200,
  13.         Msg:  "success",
  14.         Data: LoginData{
  15.                 Token:    userToken,
  16.                 Username: username,
  17.                 Location: "/static/view/home.html",
  18.         },
  19. }
复制代码
如许返回的 JSON 就是:
  1. {
  2.   "code": 200,
  3.   "msg": "success",
  4.   "data": {
  5.     "token": "...",
  6.     "username": "...",
  7.     "location": "..."
  8.   }
  9. }
复制代码
前端用 resp.data.token、resp.data.username 就不会有大小写错位的问题。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
继续阅读请点击广告
回复

使用道具 举报

快速回复 返回顶部 返回列表