在 Go 語言中,結構體字段標簽(Struct Tag) 是一種用于給字段添加元信息(metadata)的機制,常用于序列化(如 JSON、XML)、ORM 映射、驗證等場景。你在開發 Web 應用或處理數據交互時,一定會經常看到類似下面的寫法:
type User struct {Username string `json:"username"`Token string `json:"token"`
}
其中的 json:"token"
就是字段標簽,它并不影響 Go 語言本身的語法邏輯,但它在使用反射(reflect)時非常有用,特別是當你用標準庫如 encoding/json 時。
一、結構體標簽的基本語法
結構體標簽是一對反引號 ` 包起來的字符串,里面是一個鍵值對的形式:
FieldName FieldType `key:"value"`
//可以寫多個鍵值對:
FieldName FieldType `json:"token" xml:"token" validate:"required"`
這些標簽是給其他包(通常是庫)解析使用的,不影響 Go 編譯器的行為。
二、json:"token"
的具體含義
當你用 encoding/json 包將結構體編碼為 JSON 時,這個標簽的作用是:
? 指定序列化后的字段名
默認情況下,Go 會使用結構體字段名作為 JSON 的字段名。但注意:
Go 結構體的字段是大寫開頭(導出);
JSON 通常用小寫字段名(如 “token”);
為了統一后端返回格式并滿足前端規范,我們可以顯式指定字段名:
type User struct {Token string `json:"token"`
}
生成的json:
{"token": "abc123"
}
? 反序列化時也生效
當你將 JSON 反序列化成結構體時,Go 會根據標簽來找對應字段。例如上面的json格式能成功映射到:
var user User
json.Unmarshal(data, &user)
// user.Token == "abc123"
三、常見的標簽格式變體
type User struct {Token string `json:"token"` // 顯式指定字段名為 tokenAge int `json:"-"` // 忽略該字段,不進行序列化Email string `json:"email,omitempty"` // 若為空則忽略該字段
}
json:“-”: 表示這個字段永遠不會被編碼或解碼,即不導出。
json:“email,omitempty”: 表示只有字段不為默認值時,才會被編碼到 JSON(比如字符串為 “”,數字為 0 就會忽略)。
四、使用示例
package mainimport ("encoding/json""fmt"
)type User struct {Username string `json:"username"`Token string `json:"token"`Age int `json:"-"` // 不導出
}func main() {user := User{Username: "Alice",Token: "abc123",Age: 30,}data, _ := json.Marshal(user)fmt.Println(string(data))
}
//{"username":"Alice","token":"abc123"}
五、使用建議
- 字段必須導出(首字母大寫),否則即使有 tag,json 包也不會訪問它。
- 推薦統一使用小寫 JSON 字段名:json:“username”,更符合前端 JSON 風格。
- 如有嵌套結構體,注意為子結構體也添加 json 標簽。!!!~~~~~~~~!!! 務必都為添加 json 標簽的結構體!!!!不然前端解析不了!!!
疑問? 如果json tag為"-" ,為什么不把結構體首字母小寫呢 不是一個效果嗎?
?json:"-"
的用途
json:“-” 是明確告訴 encoding/json:“這個字段你不要處理,序列化/反序列化時忽略它”。這在結構體對外暴露字段但不希望被 JSON 處理時非常有用,比如:
type User struct {Username string `json:"username"`Password string `json:"-"` // 不想被輸出!
}
你仍然可以在后端處理 Password 字段,但它不會出現在 JSON 輸出中。這是安全和結構清晰性方面的明確表達。
? 總結:選擇建議
目的 | 用法推薦 |
---|---|
字段僅用于內部邏輯,不想暴露出去 | 小寫字段 |
字段對程序可見,但不想在 JSON 中出現 | json:"-" |
需要 JSON 中出現但字段名不同 | json:"your_name" |
希望字段在為空時不出現 | json:"your_name,omitempty" |
簡單例子:
type RespMsg struct {Code int `json:"code"`Msg string `json:"msg"`Data interface{} `json:"data"`
}type LoginData struct {Token string `json:"token"`Username string `json:"username"`Location string `json:"location"`
}rsp := RespMsg{Code: 200,Msg: "success",Data: LoginData{Token: userToken,Username: username,Location: "/static/view/home.html",},
}
這樣返回的 JSON 就是:
{"code": 200,"msg": "success","data": {"token": "...","username": "...","location": "..."}
}
前端用 resp.data.token、resp.data.username 就不會有大小寫錯位的問題。