在go中使用json.marshal序列化结构体切片时,若json输出为空对象(如[{},{}]),根本原因是结构体字段未导出(即首字母小写),导致json包无法访问这些字段。解决方法是将字段名首字母大写并合理使用json标签。
Go 的 encoding/json 包遵循严格的可见性规则:只有导出(exported)字段(即首字母大写的字段)才能被 JSON 编码/解码器访问。你原始定义中的 imsi、network 等字段均为小写开头,属于未导出字段,因此 json.Marshal 会忽略它们,仅生成空的 JSON 对象 {}。
✅ 正确做法如下:
修正后的类型定义示例:
type SpanInfo struct {
IMSI string `json:"imsi"`
Network string `json:"network"`
NetworkStatus string `json:"network_status"`
SignalQuality int `json:"signal_quali
ty"`
Slot int `json:"slot"`
State string `json:"state"`
}
type GatewayInfo []SpanInfo使用方式保持不变:
func getGatewayInfo(spans []SpanInfo) GatewayInfo {
return GatewayInfo(spans)
}
// 示例初始化
spans := []SpanInfo{
{IMSI: "652025105829193", Network: "20801", NetworkStatus: "Registered (Roaming)", SignalQuality: 17, Slot: 2, State: "active"},
{IMSI: "652025105829194", Network: "20801", NetworkStatus: "Registered (Roaming)", SignalQuality: 16, Slot: 3, State: "active"},
}
gatewayInfo := getGatewayInfo(spans)
jsonInfo, err := json.Marshal(gatewayInfo)
if err != nil {
log.Fatal("JSON marshal error:", err)
}
log.Printf("jsonInfo: %s", jsonInfo)
// 输出示例:
// [{"imsi":"652025105829193","network":"20801","network_status":"Registered (Roaming)","signal_quality":17,"slot":2,"state":"active"},...]⚠️ 注意事项:
总结:Go 的 JSON 序列化不是“自动反射所有字段”,而是基于导出性 + struct tag 的显式契约。养成从设计阶段就规范字段命名与标签的习惯,是写出健壮序列化逻辑的关键前提。