You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 10:33:18