Golang中Json标签的使用与解析指南
Golang中Json标签的使用与解析指南 在哪些场景下会使用字符串标签?我参考了一篇帖子并尝试相应地使用它,但失败了。 我留下我参考的帖子链接:
Go: Marshal and Unmarshal JSON with time and URL data
使用 Go json 包中的编组接口来控制 JSON 中的复杂数据类型。
我的实现方式: https://play.golang.org/p/IJrbAlSuuUU
感谢您的帮助。
更多关于Golang中Json标签的使用与解析指南的实战教程也可以访问 https://www.itying.com/category-94-b0.html
2 回复
为了在使用 string 标签时能够解析,你需要将 JSON 中的值用字符串包裹起来:
msg := `{
"id": "1",
"name": "hello",
"val": "789.33"
}`
来自文档:
“string” 选项表示一个字段在 JSON 编码的字符串内部以 JSON 形式存储。它仅适用于字符串、浮点数、整数或布尔类型的字段。这种额外的编码级别有时在与 JavaScript 程序通信时使用:
更多关于Golang中Json标签的使用与解析指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Golang中,字符串标签(string tag)主要用于控制特定类型在JSON序列化/反序列化时的行为。以下是常见使用场景和示例:
1. 时间类型格式化
type Event struct {
Timestamp time.Time `json:"timestamp,string"` // 序列化为JSON字符串
Name string `json:"name"`
}
func main() {
event := Event{
Timestamp: time.Now(),
Name: "Meeting",
}
// 序列化:时间戳变为字符串格式
data, _ := json.Marshal(event)
fmt.Println(string(data))
// 输出: {"timestamp":"2024-01-15T10:30:00Z","name":"Meeting"}
}
2. 数字类型转为字符串
type Product struct {
ID int64 `json:"id,string"` // 序列化为字符串
Price float64 `json:"price,string"` // 序列化为字符串
Name string `json:"name"`
}
func main() {
p := Product{
ID: 1001,
Price: 29.99,
Name: "Laptop",
}
data, _ := json.Marshal(p)
fmt.Println(string(data))
// 输出: {"id":"1001","price":"29.99","name":"Laptop"}
// 反序列化时也能正确解析
var p2 Product
json.Unmarshal(data, &p2)
fmt.Printf("ID: %d, Price: %.2f\n", p2.ID, p2.Price)
}
3. 大整数处理(避免JavaScript精度丢失)
type Transaction struct {
Amount int64 `json:"amount,string"` // 大整数转为字符串
Currency string `json:"currency"`
}
func main() {
t := Transaction{
Amount: 9223372036854775807, // int64最大值
Currency: "USD",
}
data, _ := json.Marshal(t)
fmt.Println(string(data))
// 输出: {"amount":"9223372036854775807","currency":"USD"}
}
4. 自定义类型实现字符串标签
type CustomInt int
func (ci *CustomInt) UnmarshalJSON(data []byte) error {
var s string
if err := json.Unmarshal(data, &s); err != nil {
return err
}
val, err := strconv.Atoi(s)
if err != nil {
return err
}
*ci = CustomInt(val)
return nil
}
func (ci CustomInt) MarshalJSON() ([]byte, error) {
return json.Marshal(strconv.Itoa(int(ci)))
}
type Data struct {
Value CustomInt `json:"value"` // 自动使用字符串格式
}
func main() {
jsonStr := `{"value":"123"}`
var d Data
json.Unmarshal([]byte(jsonStr), &d)
fmt.Printf("Value: %d\n", d.Value)
}
常见问题解决
如果遇到解析失败,检查以下几点:
- JSON格式必须匹配:
// 正确:JSON中的数字是字符串格式
jsonStr := `{"id":"1001","name":"test"}`
// 错误:JSON中的数字是数值格式
jsonStr := `{"id":1001,"name":"test"}` // 解析会失败
- 使用
json.RawMessage处理混合类型:
type Flexible struct {
Data json.RawMessage `json:"data"`
}
func main() {
jsonStr := `{"data":"string_value"}`
var f Flexible
json.Unmarshal([]byte(jsonStr), &f)
// 尝试作为字符串解析
var strVal string
if err := json.Unmarshal(f.Data, &strVal); err == nil {
fmt.Println("String value:", strVal)
}
}
字符串标签在需要精确控制JSON格式、避免数值精度丢失或与前端JavaScript交互时特别有用。确保序列化和反序列化时使用一致的格式即可避免解析失败。

