Golang json Unmarshal字段为空怎么办

来源:网站建设作者:零壳头衔:程序员
导读:本期聚焦于小伙伴创作的《Golang json Unmarshal字段为空怎么办》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Golang json Unmarshal字段为空怎么办》有用,将其分享出去将是对创作者最好的鼓励。

在Golang开发中,处理JSON数据是常见需求,使用encoding/json包的Unmarshal方法可以将JSON字符串转换为结构体实例,但很多开发者会遇到转换后部分字段为空的问题,这本质上是JSON数据和结构体的映射规则不匹配导致的。

Golang json Unmarshal字段为空怎么办

常见的字段为空原因及解决方法

1. 结构体字段未导出

Golang的JSON反序列化只会处理导出的字段,也就是首字母大写的字段,如果结构体字段首字母小写,Unmarshal无法为其赋值,就会出现字段为空的情况。

示例代码如下:

package main

import (
	"encoding/json"
	"fmt"
)

// 错误示例:字段未导出
type UserWrong struct {
	name string // 首字母小写,未导出
	Age  int
}

// 正确示例:字段导出
type UserRight struct {
	Name string // 首字母大写,导出
	Age  int
}

func main() {
	jsonStr := `{"name":"张三","age":20}`
	var wrongUser UserWrong
	json.Unmarshal([]byte(jsonStr), &wrongUser)
	fmt.Println("错误结构体结果:", wrongUser) // 输出:错误结构体结果: { 20},Name字段为空

	var rightUser UserRight
	json.Unmarshal([]byte(jsonStr), &rightUser)
	fmt.Println("正确结构体结果:", rightUser) // 输出:正确结构体结果: {张三 20}
}

2. JSON键名和结构体标签不匹配

如果JSON中的键名和结构体字段名大小写不一致,或者键名和字段名完全不同,可以通过结构体标签指定映射关系,否则字段会为空。

结构体标签的格式为json:"键名",注意标签内容中的引号是必须的,标签本身是结构体的一部分,不需要转义。

package main

import (
	"encoding/json"
	"fmt"
)

type Product struct {
	ProductName string `json:"product_name"` // 映射JSON中的product_name键
	Price       float64 `json:"price"`
	Stock       int     `json:"stock_count"` // 映射JSON中的stock_count键
}

func main() {
	jsonStr := `{"product_name":"笔记本","price":4999.99,"stock_count":100}`
	var p Product
	json.Unmarshal([]byte(jsonStr), &p)
	fmt.Println(p) // 输出:{笔记本 4999.99 100}

	// 如果JSON键名和字段名一致但大小写不同,也需要标签或者字段名和JSON键名完全匹配
	type Product2 struct {
		ProductName string // JSON键名是productName的话,这里不会匹配,需要加标签`json:"productName"`
	}
}

3. 数据类型不匹配

JSON中的数据类型和结构体中字段的类型不一致时,Unmarshal会无法赋值,导致字段为空。比如JSON中是字符串类型的数字,而结构体字段是int类型,或者JSON中是数组,结构体字段是字符串等。

package main

import (
	"encoding/json"
	"fmt"
)

type Order struct {
	OrderID int     `json:"order_id"`
	Amount  float64 `json:"amount"`
	Items   string  `json:"items"` // 错误:JSON中items是数组,这里定义为字符串
}

func main() {
	jsonStr := `{"order_id":1001,"amount":299.5,"items":["商品1","商品2"]}`
	var o Order
	json.Unmarshal([]byte(jsonStr), &o)
	fmt.Println(o) // 输出:{1001 299.5 },Items字段为空
}

4. JSON值为null

如果JSON中某个键的值是null,反序列化到普通类型字段时,会保持该类型的零值,比如字符串是空字符串,int是0,看起来像是字段为空。如果需要区分null和零值,可以使用指针类型或者sql.NullString等可空类型。

package main

import (
	"encoding/json"
	"fmt"
)

type UserInfo struct {
	Nickname *string `json:"nickname"` // 使用指针类型,null时指针为nil
	City     string  `json:"city"`
}

func main() {
	jsonStr1 := `{"nickname":"小明","city":"北京"}`
	var u1 UserInfo
	json.Unmarshal([]byte(jsonStr1), &u1)
	fmt.Println("昵称:", *u1.Nickname, "城市:", u1.City) // 输出:昵称: 小明 城市: 北京

	jsonStr2 := `{"nickname":null,"city":"上海"}`
	var u2 UserInfo
	json.Unmarshal([]byte(jsonStr2), &u2)
	if u2.Nickname == nil {
		fmt.Println("昵称为null")
	}
	fmt.Println("城市:", u2.City) // 输出:昵称为null 城市: 上海
}

Golang JSON映射核心规则总结

为了更清晰地了解映射规则,以下是核心规则整理:

规则项说明
字段导出要求只有首字母大写的导出字段才能被Unmarshal赋值
键名匹配优先级优先匹配json标签指定的键名,其次匹配字段名的首字母小写形式,最后匹配字段名本身
类型匹配要求JSON值的类型必须和结构体字段类型兼容,否则无法赋值
null值处理普通类型null会转为零值,指针类型null会转为nil

调试技巧

如果遇到字段为空的问题,可以先打印Unmarshal返回的error,查看是否有类型不匹配的提示:

package main

import (
	"encoding/json"
	"fmt"
)

type Test struct {
	Num int `json:"num"`
}

func main() {
	jsonStr := `{"num":"abc"}` // 字符串无法转为int
	var t Test
	err := json.Unmarshal([]byte(jsonStr), &t)
	if err != nil {
		fmt.Println("反序列化错误:", err) // 输出:反序列化错误: json: cannot unmarshal string into Go struct field Test.num of type int
	}
}

通过以上规则和示例,开发者可以快速定位Golang json Unmarshal字段为空的问题,正确配置结构体完成JSON数据的映射。

Golangjson_UnmarshalJSON映射规则结构体字段修改时间:2026-06-24 01:24:43

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。