发布于2026-07-18 阅读(0)
扫一扫,手机访问
在Go语言中,用json.Unmarshal做反序列化时,有个很常见的坑:结构体字段读出来全是零值——明明JSON里数据好好的,但就是填不进去。问题出在哪?其实就是字段名首字母小写,属于未导出字段,反射机制根本访问不到。
具体来说,encoding/json包通过反射来读写结构体,但反射只能操作导出字段(首字母大写的)。回到原代码,PDPOffer里的字段比如cart_value、discount_amount_default、max_discount全是小写开头,自然是未导出,结果json.Unmarshal没法写入,最终结构体字段全保持零值(0、空字符串之类的),而不是JSON里的实际值。

✅ 正确做法其实很简单:把结构体字段改成导出形式,再通过json标签声明对应的JSON键名就行:
type PDPOffer struct {
CartValue int `json:"cart_value"`
DiscountAmountDefault int `json:"discount_amount_default"`
MaxDiscount string `json:"max_discount"`
}
另外,类型也得对上。比如上面例子中JSON里的"max_discount": 2是个整数,但结构体字段MaxDiscount定义成了string,这就会反序列化失败,报错说"cannot unmarshal number into Go struct field PDPOffer.MaxDiscount of type string"。所以务必要确保类型一致,比如:
// 若JSON中max_discount为数字(如2),则字段应为int或float64 MaxDiscount int `json:"max_discount"`
修正后的完整示例:
package main
import (
"encoding/json"
"fmt"
)
func main() {
type PDPOffer struct {
CartValue int `json:"cart_value"`
DiscountAmountDefault int `json:"discount_amount_default"`
MaxDiscount int `json:"max_discount"` // 类型与JSON值一致
}
data := map[string]interface{}{
"cart_value": 1,
"max_discount": 2,
"discount_amount_default": 5,
}
jsonBytes, err := json.Marshal(data)
if err != nil {
panic(err)
}
var offer PDPOffer
if err := json.Unmarshal(jsonBytes, &offer); err != nil {
panic(err)
}
fmt.Printf("%+v\n", offer) // 输出:{CartValue:1 DiscountAmountDefault:5 MaxDiscount:2}
}
注意事项:
*string)或omitempty标签来提升健壮性。遵循这些规范,就能确保json.Unmarshal正确填充结构体字段,避开零值陷阱。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8