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

Go语言int枚举类型JSON编解码报错问题求助

解决Go中int枚举序列化为JSON字符串的问题

我来帮你搞定这个int枚举转JSON字符串的问题~你遇到的报错,大概率是因为MarshalJSON的写法有小问题,或者没配合实现对应的UnmarshalJSON方法导致的,下面给你完整的可行方案:

1. 完整的枚举类型与序列化实现

首先定义你的int枚举类型,实现Stringer接口,再正确编写MarshalJSON和UnmarshalJSON方法:

package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"strings"
)

// trxStatus 基于int的交易状态枚举
type trxStatus int

const (
	TrxStatusPending trxStatus = iota
	TrxStatusSuccess
	TrxStatusFailed
)

// String 实现Stringer接口,返回枚举对应的字符串标识
func (s trxStatus) String() string {
	switch s {
	case TrxStatusPending:
		return "pending"
	case TrxStatusSuccess:
		return "success"
	case TrxStatusFailed:
		return "failed"
	default:
		return "unknown"
	}
}

// MarshalJSON 将枚举序列化为带双引号的JSON字符串
func (s trxStatus) MarshalJSON() ([]byte, error) {
	// 使用格式化字符串生成合法的JSON字符串,比手动拼接引号更安全
	return []byte(fmt.Sprintf(`"%s"`, s.String())), nil
}

// UnmarshalJSON 从JSON字符串反序列化为枚举值
func (s *trxStatus) UnmarshalJSON(data []byte) error {
	// 先去除JSON字符串的前后双引号
	str := strings.Trim(string(data), `"`)
	// 映射字符串到对应的枚举值
	switch str {
	case "pending":
		*s = TrxStatusPending
	case "success":
		*s = TrxStatusSuccess
	case "failed":
		*s = TrxStatusFailed
	default:
		return errors.New(fmt.Sprintf("无效的交易状态: %s", str))
	}
	return nil
}

2. 分析你之前的问题

你提到的报错invalid character 'b' looking for beginning of value,可能来自这几个原因:

  • 语法错误:你写的MarshalJSON代码里有括号错位(比如return []byte("\"" + s.String() + "\"") }, nil }这里多了一个闭合括号),导致代码运行时出现异常
  • JSON格式不合法:如果手动拼接引号时,你的String()方法返回的字符串包含未转义的特殊字符(比如双引号),会生成非法的JSON,引发解析错误
  • 未实现对应UnmarshalJSON:如果只实现了序列化方法,后续反序列化时也会因为格式不匹配报错

3. 测试验证

写个简单的main函数测试序列化和反序列化:

func main() {
	// 测试序列化
	status := TrxStatusSuccess
	data, err := json.Marshal(status)
	if err != nil {
		fmt.Printf("序列化错误: %v\n", err)
		return
	}
	fmt.Printf("序列化结果: %s\n", data) // 输出:"success"

	// 测试反序列化
	var newStatus trxStatus
	err = json.Unmarshal(data, &newStatus)
	if err != nil {
		fmt.Printf("反序列化错误: %v\n", err)
		return
	}
	fmt.Printf("反序列化结果: 枚举值=%d, 字符串=%s\n", newStatus, newStatus.String()) 
	// 输出:枚举值=1, 字符串=success
}

这样就能正常实现int枚举和JSON字符串的互相转换啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:32:50