golang encoding/json 指定结构体 json 序列化后的属性名称
在 Go 语言中,结构体(struct)与 JSON 之间的序列化和反序列化主要依赖于标准库 encoding/json
。默认情况下,序列化时会直接使用结构体字段名作为 JSON
的键,但很多时候我们需要自定义输出的属性名称,这就需要用到 结构体标签(struct tag)。
使用 struct tag 指定 JSON 字段名
Go 提供了灵活的标签机制,可以通过在字段后面加上 `json:"xxx"`
来指定序列化后的属性名称。例如:
复制
展开
type User struct {
ID int `json:"id"`
Name string `json:"username"`
Email string `json:"email_addr"`
}
序列化后的结果:
复制
展开
{
"id": 1,
"username": "Alice",
"email_addr": "alice@example.com"
}
常见标签用法
- 指定字段名
复制
展开
Name string `json:"username"`
将 Name
序列化为 username
。
- 忽略字段
复制
展开
Password string `json:"-"`
该字段不会出现在 JSON 中。
- 忽略零值
复制
展开
Age int `json:"age,omitempty"`
如果 Age == 0
,该字段不会出现在 JSON 中。
- 嵌套结构体 对嵌套结构体也可以使用标签,保持 JSON 输出更贴合需求。
反序列化时属性映射
struct tag 不仅在序列化时生效,在反序列化(json.Unmarshal
)时同样适用。只要 JSON 中的键和标签定义的名称一致,就会自动映射到对应字段。
示例
复制
展开
package main
import (
"encoding/json"
"fmt"
)
type User struct {
ID int `json:"id"`
Name string `json:"username"`
Email string `json:"email_addr"`
}
func main() {
jsonStr := `{"id":100,"username":"Bob","email_addr":"bob@example.com"}`
var u User
if err := json.Unmarshal([]byte(jsonStr), &u); err != nil {
panic(err)
}
fmt.Printf("反序列化结果: %+v\n", u)
}
运行结果:
复制
展开
反序列化结果: {ID:100 Name:Bob Email:bob@example.com}
可以看到,JSON 的键自动映射到了对应的结构体字段。
进阶技巧
- 大小写不一致 如果没有指定标签,Go 默认使用字段名(区分大小写)。这意味着字段必须是导出的(首字母大写),否则不会被序列化。
复制
展开
type Test struct {
Name string // 会被序列化
age int // 小写开头,不会被序列化
}
- 多名称兼容(反序列化) 可以在标签里写多个名字(逗号分隔),反序列化时会依次尝试匹配。
复制
展开
type User struct {
Name string `json:"name,fullname"`
}
如果 JSON 中有 name
或 fullname
,都会映射到 Name
字段。
- 动态字段处理
对于未知字段,可以用
map[string]interface{}
或json.RawMessage
来接收。
复制
展开
var data map[string]interface{}
json.Unmarshal([]byte(`{"extra":"value"}`), &data)
总结
在 Go 中通过 struct tag 可以灵活地控制 JSON 序列化后的属性名称和输出规则,同时在反序列化时也能自动映射对应字段。这不仅能让代码与外部接口保持一致,还能避免冗余字段,提升数据交互的可控性。
作者:https://blog.xn--rpv331d.com/望舒
链接:https://blog.xn--rpv331d.com/望舒/blog/116
转载注意保留文章出处...
No data