Golang反序列化含proto类型map的结构体时无法获取嵌套字段值
问题根因
你编写的JSON结构符合对应proto定义的JSON映射规范,本身没有错误,解析失败的核心原因有两个:
gw.InferParameter是protobuf生成的oneof类型字段,标准库encoding/json不识别proto oneof类型的序列化规则,反序列化时无法将int64Param字段映射到对应的Go结构体成员,最终只能得到一个空的InferParameter实例。- protobuf生成的Go结构体本身就不是设计给标准
encoding/json包解析的,官方有专门的JSON序列化/反序列化实现,直接用标准库解析本身就是错误用法。
修复方案
最稳妥的方式是替换为proto官方的JSON解析库protojson,完全兼容proto的JSON映射规范,不需要修改你现有的JSON请求结构:
package main import ( "fmt" "google.golang.org/protobuf/encoding/protojson" gw "github.com/kserve/rest-proxy/gen" ) func main() { d := &gw.ModelInferRequest{} data := ` { "id": "1", "inputs": [{ "name": "input:0", "shape": [-1, -1, -1, -1], "datatype": "UINT8", "parameters": { "binary_data_size": { "int64Param": 100 } } }] } ` if err := protojson.Unmarshal([]byte(data), d); err != nil { fmt.Println("反序列化失败:", err) return } // 读取binary_data_size的值 for _, input := range d.Inputs { param, exists := input.Parameters["binary_data_size"] if !exists { continue } // 断言oneof的具体类型 int64Param, ok := param.ParameterChoice.(*gw.InferParameter_Int64Param) if ok { fmt.Println("binary_data_size的取值为:", int64Param.Int64Param) // 输出100 } } }
注意:使用protojson后你不需要自定义额外的REST结构体,直接用生成的
gw.ModelInferRequest结构体接收参数即可。
如果你因为特殊原因必须使用标准库encoding/json,需要自定义一个和标准JSON tag匹配的临时结构体来接收parameters字段,反序列化完成后手动转换为proto对应的InferParameter类型,这种方式冗余度高,不推荐使用。
内容的提问来源于stack exchange,提问作者JR Wink
相关产品推荐
相关产品推荐

