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

Go语言JSON反序列化:将数组字段保留为JSON字符串的问题

解决Go JSON反序列化时将数组保留为JSON字符串的问题

这个panic的原因很直白:Go的JSON包默认会尝试把JSON数组直接映射到string类型字段,类型不匹配自然会触发错误。要实现把数组原样保留为JSON字符串,我们可以通过自定义JSON反序列化逻辑来解决,下面是具体方案:


方法一:自定义类型实现json.Unmarshaler接口

这是最灵活的方案,我们可以定义一个字符串别名类型,通过实现UnmarshalJSON方法接管反序列化过程:

  1. 定义自定义类型
// RawJSONString 是string的别名,专门用于存储原始JSON格式的字符串
type RawJSONString string
  1. 实现json.Unmarshaler接口
func (r *RawJSONString) UnmarshalJSON(data []byte) error {
    // 直接把原始的JSON字节数组转成字符串存储,跳过类型转换逻辑
    *r = RawJSONString(data)
    return nil
}
  1. 修改你的Thing结构体
    把原来的B string替换成我们的自定义类型:
type Thing struct {
    A int           `json:"a"`
    B RawJSONString `json:"b"` // 使用自定义类型接收原始JSON
}
  1. 测试验证
package main

import (
    "encoding/json"
    "fmt"
)

type RawJSONString string

func (r *RawJSONString) UnmarshalJSON(data []byte) error {
    *r = RawJSONString(data)
    return nil
}

type Thing struct {
    A int           `json:"a"`
    B RawJSONString `json:"b"`
}

func main() {
    jsonData := []byte(`{"a": 1, "b": [1,2,3,4]}`)
    var t Thing
    if err := json.Unmarshal(jsonData, &t); err != nil {
        panic(err)
    }

    fmt.Printf("A: %d\n", t.A)
    fmt.Printf("B (JSON字符串): %s\n", t.B)
    // 输出结果:
    // A: 1
    // B (JSON字符串): [1,2,3,4]

    // 如果之后需要把B转回数组,也很方便:
    var bSlice []int
    if err := json.Unmarshal([]byte(t.B), &bSlice); err != nil {
        panic(err)
    }
    fmt.Printf("B转回数组: %v\n", bSlice)
}

方法二:使用json.RawMessage(轻量快捷方案)

如果你不想额外定义类型,也可以直接用Go标准库的json.RawMessage,它本质是[]byte的别名,能直接存储原始JSON数据,之后再转成字符串即可:

import "encoding/json"

type Thing struct {
    A int             `json:"a"`
    B json.RawMessage `json:"b"`
}

func main() {
    jsonData := []byte(`{"a": 1, "b": [1,2,3,4]}`)
    var t Thing
    if err := json.Unmarshal(jsonData, &t); err != nil {
        panic(err)
    }

    // 转成字符串使用
    bStr := string(t.B)
    fmt.Printf("B: %s\n", bStr) // 输出: [1,2,3,4]
}

这种方案的优势是无需额外定义类型,适合快速实现;缺点是B的类型是json.RawMessage(本质是字节数组),如果需要频繁作为字符串使用,每次都要手动转换,不如自定义类型顺手。


两种方案的核心思路都是保留原始JSON字节数据,跳过JSON包默认的类型转换逻辑,完美解决你遇到的类型不匹配问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:31:42