本文深入探讨go语言中处理json数据时常见的“json: cannot unmarshal number into go value”错误。通过分析go结构体定义与json数据类型不匹配的根源,重点讲解如何正确映射数组类型和处理可空(null)数值,并提供具体的代码示例和最佳实践,旨在帮助开发者有效解决json反序列化中的类型不一致问题。
在Go语言中,使用encoding/json包进行JSON数据的反序列化(Unmarshal)是常见的操作。然而,当Go结构体(struct)的字段类型与传入的JSON数据类型不完全匹配时,就会出现“json: cannot unmarshal number into Go value of type ...”这样的错误。这通常意味着JSON中期望的是一个数字,但Go结构体中定义的类型无法直接接收这个数字,或者反之。
考虑以下JSON数据片段和对应的Go结构体定义:
原始JSON数据片段:
{
"Teams": [
[
{
"ID": 1,
"HP": 10,
"CT": 0,
"Stats": [1, 1, 1, 1, 1, 1], // 注意这里是一个数字数组
"X": 0,
"Y": 0,
"ACList": {
"Actions": [],
"TICKCT": 0
}
}
]
],
"Map": [
[
{
"Depth": 1,
"Type": 1,
"Unit": 1 // 注意这里可以是数字或null
},
{
"Depth": 1,
"Type": 1,
"Unit": null
}
]
],
"ID": "0b055e19-9b96-e492-b816-43297f12cc39"
}原始Go结构体定义:
type Match struct {
Teams [][]Char
Map [][]Tile
ID string
// Socket *websocket.Conn `json:'-'` // 忽略此字段
}
type Char struct {
ID int
HP int
CT int
Stats statList // 问题所在:JSON中是数组,这里是结构体
X int
Y int
ACList Actions
}
type statList struct {
Str int
Vit int
Int int
Wis int
Dex int
Spd int
}
type Tile struct {
Depth int
Type int
Unit int // 问题所在:JSON中可以是null,这里是int
}
// 其他辅助结构体,假设正确
type Actions struct {
Actions []Action
TICKCT int
}
type Action string // 假设Action是字符串类型当我们尝试将上述JSON数据反序列化到Match结构体时,会遇到类似以下的错误:
json: cannot unmarshal number into Go value of type main.Char
这个错误信息提示我们,在反序列化Char类型时,遇到了无法将数字反序列化到其某个字段的问题。根据JSON数据和Go结构体,可以定位到两个主要的不匹配点:
要解决这些类型不匹配问题,我们需要根据JSON数据的实际结构调整Go结构体的字段类型。
由于JSON中的Stats是一个整数数组,Go结构体中的Stats字段也应该定义为整数切片(slice)。
修改前:
type Char struct {
// ...
Stats statList
// ...
}
type statList struct {
Str int
Vit int
Int int
Wis int
Dex int
Spd int
}修改后:
type Char struct {
// ...
Stats []int // 将statList改为[]int
// ...
}
// statList结构体在此场景下不再需要,除非JSON中Stats是一个包含Str, Vit等字段的对象如果JSON字段可能为null,而对应的Go字段是基本类型(如int, bool, float64, string),则需要使用指针类型来表示其可空性。*int类型可以接收int值或nil(对应JSON的null)。
修改前:
type Tile struct {
Depth int
Type int
Unit int // 无法接收null
}修改后:
type Tile struct {
Depth int
Type int
Unit *int // 使用指针类型,可接收int或nil
}将上述修改应用到所有相关的Go结构体后,完整的示例代码如下:
package main
import (
"encoding/json"
"fmt"
)
// Match结构体,保持不变
type Match struct {
Teams [][]Char
Map [][]Tile
ID string //uuid
// Socket *websocket.Conn `json:'-'` // 如果有websocket连接,通常不进行JSON序列化/反序列化
}
// Char结构体,修正Stats字段
type Char struct {
ID int
HP int
CT int
Stats []int // 修正:JSON中是数组,改为[]int
X int
Y int
ACList Actions
}
// Actions结构体,保持不变
type Actions struct {
Actions []Action
TICKCT int
}
// Action类型,假设是字符串
type Action string
// T
ile结构体,修正Unit字段以处理null值
type Tile struct {
Depth int
Type int
Unit *int // 修正:JSON中可能为null,使用*int
}
// 示例JSON数据
var jsonData = `{
"Teams": [
[
{
"ID": 1,
"HP": 10,
"CT": 0,
"Stats": [
1,
1,
1,
1,
1,
1
],
"X": 0,
"Y": 0,
"ACList": {
"Actions": [],
"TICKCT": 0
}
}
],
[
{
"ID": 2,
"HP": 10,
"CT": 0,
"Stats": [
1,
1,
1,
1,
1,
1
],
"X": 2,
"Y": 2,
"ACList": {
"Actions": [],
"TICKCT": 0
}
}
]
],
"Map": [
[
{
"Depth": 1,
"Type": 1,
"Unit": 1
},
{
"Depth": 1,
"Type": 1,
"Unit": null
},
{
"Depth": 1,
"Type": 1,
"Unit": null
}
],
[
{
"Depth": 1,
"Type": 1,
"Unit": null
},
{
"Depth": 1,
"Type": 1,
"Unit": null
},
{
"Depth": 1,
"Type": 1,
"Unit": null
}
],
[
{
"Depth": 1,
"Type": 1,
"Unit": null
},
{
"Depth": 1,
"Type": 1,
"Unit": null
},
{
"Depth": 1,
"Type": 1,
"Unit": 2
}
]
],
"ID": "0b055e19-9b96-e492-b816-43297f12cc39"}`
func main() {
match := new(Match)
err := json.Unmarshal([]byte(jsonData), match)
if err != nil {
panic(fmt.Errorf("JSON unmarshal error: %w", err))
}
fmt.Printf("成功反序列化Match对象: %#v\n", match)
// 验证部分数据
if len(match.Teams) > 0 && len(match.Teams[0]) > 0 {
char1 := match.Teams[0][0]
fmt.Printf("第一个Char的Stats: %v\n", char1.Stats)
}
if len(match.Map) > 0 && len(match.Map[0]) > 1 {
tileWithUnit := match.Map[0][0]
tileWithNullUnit := match.Map[0][1]
fmt.Printf("第一个Tile的Unit: %v\n", tileWithUnit.Unit) // 应该输出&1
fmt.Printf("第二个Tile的Unit: %v\n", tileWithNullUnit.Unit) // 应该输出
}
} 运行上述代码将不再报错,并能正确地将JSON数据反序列化到Go结构体中。
“json: cannot unmarshal number into Go value”错误是Go语言JSON处理中常见的类型不匹配问题。通过仔细比对JSON数据的结构和Go结构体字段的定义,特别是关注数组类型、可空值以及json Tag的正确使用,可以有效地避免和解决这类问题。遵循Go语言的类型系统和encoding/json包的映射规则,是编写健壮JSON处理代码的关键。
# js
# json
# go
# go语言
# websocket
# ai
# json处理
# json数组
# 数据类型
# String
# NULL
# 字符串
# 结构体
# bool
# char
# int
# 指针
# 指针类型
# Struct
# Interface
相关文章:
广州网站设计制作一条龙,广州巨网网络科技有限公司是干什么的?
如何在腾讯云免费申请建站?
详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)
平台云上自助建站如何快速打造专业网站?
外汇网站制作流程,如何在工商银行网站上做外汇买卖?
logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?
一键网站制作软件,义乌购一件代发流程?
公司网站的制作公司,企业网站制作基本流程有哪些?
php8.4新语法match怎么用_php8.4match表达式替代switch【方法】
如何通过虚拟主机空间快速建站?
如何配置FTP站点权限与安全设置?
免费网站制作模板下载,除了易企秀之外还有什么H5平台可以制作H5长页面,最好是免费的?
如何基于云服务器快速搭建网站及云盘系统?
如何彻底卸载建站之星软件?
香港服务器网站卡顿?如何解决网络延迟与负载问题?
网站规划与制作是什么,电子商务网站系统规划的内容及步骤是什么?
招商网站制作流程,网站招商广告语?
制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?
手机怎么制作网站教程步骤,手机怎么做自己的网页链接?
如何用狗爹虚拟主机快速搭建网站?
海南网站制作公司有哪些,海口网是哪家的?
如何通过免费商城建站系统源码自定义网站主题与功能?
c++怎么实现高并发下的无锁队列_c++ std::atomic原子变量与CAS操作【详解】
如何用西部建站助手快速创建专业网站?
如何通过WDCP绑定主域名及创建子域名站点?
网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?
建站之星后台管理:高效配置与模板优化提升用户体验
如何快速搭建支持数据库操作的智能建站平台?
网站制作软件免费下载安装,有哪些免费下载的软件网站?
北京制作网站的公司,北京铁路集团官方网站?
建站之星手机一键生成:多端自适应+小程序开发快速建站指南
如何快速配置高效服务器建站软件?
建站之星伪静态规则如何设置?
在线ppt制作网站有哪些,请推荐几个好的课件下载的网站?
如何在新浪SAE免费搭建个人博客?
小自动建站系统:AI智能生成+拖拽模板,多端适配一键搭建
想学网站制作怎么学,建立一个网站要花费多少?
红河网站制作公司,红河事业单位身份证如何上传?
如何处理“XML格式不正确”错误 常见XML well-formed问题解决方法
齐河建站公司:营销型网站建设与SEO优化双核驱动策略
如何正确下载安装西数主机建站助手?
浙江网站制作公司有哪些,浙江栢塑信息技术有限公司定制网站做的怎么样?
建站之星伪静态规则如何正确配置?
如何基于PHP生成高效IDC网络公司建站源码?
西安制作网站公司有哪些,西安货运司机用的最多的app或者网站是什么?
建站之星多图banner生成与模板自定义指南
如何通过商城免费建站系统源码自定义网站主题?
开源网站制作软件,开源网站什么意思?
建站之星×万网:智能建站系统+自助建站平台一键生成
台州网站建设制作公司,浙江手机无犯罪记录证明怎么开?
*请认真填写需求信息,我们会在24小时内与您取得联系。