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

如何解析包含不同类型元素的JSON-RPC中的key数组?

解决Go中JSON混合类型数组的解析问题

针对你遇到的JSON-RPC响应中key数组包含字符串、整数混合类型的解析问题,提供两种可行方案:

方案一:用[]interface{}临时接收,手动转换类型

这种方式简单直接,适合快速实现,但需要手动处理类型断言,若JSON结构不符合预期会引发运行时错误:

修改JsonRpcEntry的Key字段定义:

type JsonRpcEntry struct {
    Key []interface{}       `json:"key"`
    Val JsonRpcEntry_Val    `json:"val"`
}

解析完成后手动转换每个元素的类型:

// 遍历entries处理每个key
for _, entry := range entries {
    // 断言第一个元素为字符串
    str1, ok := entry.Key[0].(string)
    if !ok {
        // 处理类型不匹配错误
    }
    // JSON数字默认解析为float64,转换为int
    numFloat, ok := entry.Key[1].(float64)
    intNum := int(numFloat)
    if !ok {
        // 处理类型不匹配错误
    }
    // 断言第三个元素为字符串
    str2, ok := entry.Key[2].(string)
    if !ok {
        // 处理类型不匹配错误
    }
    // 后续使用str1、intNum、str2即可
}

方案二:自定义类型实现UnmarshalJSON,严格校验结构

这种方式更严谨,能在解析阶段就校验key数组的结构和类型,避免后续类型断言的繁琐:

  1. 定义对应key结构的自定义类型:
type KeyTuple struct {
    Str1 string
    Num  int
    Str2 string
}
  1. 为KeyTuple实现UnmarshalJSON方法:
import "fmt"
import "encoding/json"

func (kt *KeyTuple) UnmarshalJSON(data []byte) error {
    var arr []interface{}
    if err := json.Unmarshal(data, &arr); err != nil {
        return err
    }
    // 校验数组长度是否为3
    if len(arr) != 3 {
        return fmt.Errorf("key数组长度必须为3")
    }
    // 解析第一个元素为字符串
    var ok bool
    kt.Str1, ok = arr[0].(string)
    if !ok {
        return fmt.Errorf("key第一个元素必须是字符串")
    }
    // 解析第二个元素为整数(JSON数字默认是float64,需转换)
    numFloat, ok := arr[1].(float64)
    if !ok {
        return fmt.Errorf("key第二个元素必须是整数")
    }
    kt.Num = int(numFloat)
    // 解析第三个元素为字符串
    kt.Str2, ok = arr[2].(string)
    if !ok {
        return fmt.Errorf("key第三个元素必须是字符串")
    }
    return nil
}
  1. 修改JsonRpcEntry的Key字段为自定义类型:
type JsonRpcEntry struct {
    Key KeyTuple            `json:"key"`
    Val JsonRpcEntry_Val    `json:"val"`
}
  1. 正常解析即可,解析过程中会自动校验类型:
jsonResult := JsonRpcRsp{}
if err := json.Unmarshal(data, &jsonResult); err != nil {
    // 处理解析错误
}
entries := []JsonRpcEntry{}
if err := json.Unmarshal(jsonResult.Result, &entries); err != nil {
    // 处理解析错误(比如key结构不符合要求)
}
// 直接使用entries中每个entry的Key.Str1、Key.Num、Key.Str2

另外注意你原代码中的循环错误:for _, val := range jsonResult是错误的,因为jsonResult是结构体而非数组,正确做法是直接对jsonResult.Result进行反序列化,如上述代码所示。

内容的提问来源于stack exchange,提问作者ipStack

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 05:36:00