Go如何实现json字符串与各类struct相互转换
来源:脚本之家
2023-01-07 21:25:52
0浏览
收藏
IT行业相对于一般传统行业,发展更新速度更快,一旦停止了学习,很快就会被行业所淘汰。所以我们需要踏踏实实的不断学习,精进自己的技术,尤其是初学者。今天golang学习网给大家整理了《Go如何实现json字符串与各类struct相互转换》,聊聊字符串、Struct、JSON,我们一起来看看吧!
json字符串与各类struct相互转换
不废话了都在代码中了
package main
import (
"fmt"
"reflect"
"encoding/json"
"strings"
)
type Class struct {
Grade int `json:"grade"` //年级
ClassNumber int `json:"classNumber"` //班级号
}
type Student struct{
Name string //大写开头,可被导出,没有`json:".."`,导出json的字段名是原本名称
age int //小写开题,不可被导出
Hight int `json:"currentHight"` //导出对应json的字段名为currentHight
Class *Class `class` //指针,指向引用对象;如果不用指针,只是值复制
}
func doMarshal(){//对象转json字符串
nClass:=new(Class)//new只给给特定类型分配内存,设置“零”值,返回其地址(指针)
fmt.Printf("nClass的类型是%s,内容是%v\n",reflect.TypeOf(nClass),*nClass)
nClass.Grade=3
nClass.ClassNumber=6
nStudents:=make([]*Student,0)
//make只用于map,slice和channel,并且不显示返回指针
//这个切片,存放Student的指针
nStudent:=Student{"Lily",7,116,nClass}
jsonBytes,err1:=json.Marshal(nStudent)//解析后的是[]byte
if err1!=nil{
fmt.Printf("转json失败:%v\n",err1)
return
}
fmt.Println("转成的JSON:") //age不会被导出
//{"Name":"Lily","currentHight":116,"Class":{"grade":3,"classNumber":6}}
fmt.Println(string(jsonBytes))
nStudents=append(nStudents,&Student{"Lilei",8,130,nClass})
nStudents=append(nStudents,&nStudent)
josnListBytes,err2:=json.Marshal(nStudents)
if err2!=nil{
fmt.Printf("转jsonList失败:%v\n",err2)
return
}
fmt.Println("转成的列表型JSON:")
fmt.Println(string(josnListBytes))
//[{"Name":"Lilei","currentHight":130,"Class":{"grade":3,"classNumber":6}},{"Name":"Lily","currentHight":116,"Class":{"grade":3,"classNumber":6}}]
}
func doUnMarshal(){//json字符串转对象
jsonStr:=`
{
"Name":"Lily",
"currentHight":116,
"age":12,
"Class":{
"grade":3,
"classNumber":6
},
"score":[98,100,95]
}
`
jsonListStr:=`[
{
"Name":"Lucy",
"currentHight":120,
"Class":{
"grade":3,
"classNumber":5
}
},
{
"Name":"Lily",
"currentHight":116,
"Class":{
"grade":3,
"classNumber":6
}
}
]`
//第一种解析json方式,解析到Struct/[]Struct
student:=Student{}//同new(Student)
err:=json.Unmarshal([]byte(jsonStr),&student)
//Unmarshall第2个参数必须是指针,否则报错:json: Unmarshal(non-pointer main.Student)
//因为必须解析到具体的对象,所以需传入对象引用,而不是值传递
//score在Student中没有此字段,所以被忽略了
if err!=nil{
fmt.Printf("解析json字符串异常:%s\n",err)
}
fmt.Printf("学生的名称是%v,班级信息是%v,年龄是%v(私有对象不能导入,初始为0)\n",student.Name,*student.Class,student.age)
//学生的名称是Lily,学生的班级信息是{3 6},学生的年龄是0
students:=[]*Student{} //定义切片,同make([]*Student,0)
err=json.Unmarshal([]byte(jsonListStr),&students)
if err!=nil{
fmt.Printf("解析json字符串异常:%s\n",err)
}
for _,stu:=range students{ //这里stu是指针类型,获取其属性可以直接用.Name,也可以解引用后用.Name
fmt.Printf("列表:学生的名称是%s,身高是%d,在%d年级%d班\n",stu.Name,(*stu).Hight,(*stu.Class).Grade,stu.Class.ClassNumber)
}
//第二种解析到interface{}/[]interface{}
fmt.Println("*************解析json*************")
var student1 interface{}
err=json.Unmarshal([]byte(jsonStr),&student1)
if err!=nil{
fmt.Printf("解析json字符串异常:%s\n",err)
}
c:=-1
resolve2JosnObj(student1,c)
/*
*************解析json*************
map元素:
map[Name]的元素: 类型是string,值是 Lily
map[currentHight]的元素: 类型float64,值是 116
map[age]的元素: 类型float64,值是 12
map[Class]的元素: map元素:
---map[classNumber]的元素: 类型float64,值是 6
---map[grade]的元素: 类型float64,值是 3
map[score]的元素: list元素:
---第0个元素: 类型float64,值是 98
---第1个元素: 类型float64,值是 100
---第2个元素: 类型float64,值是 95
*/
fmt.Println("*************解析jsonlist*************")
var students1 interface{}
err=json.Unmarshal([]byte(jsonListStr),&students1)
if err!=nil{
fmt.Printf("解析jsonlist字符串异常:%s\n",err)
}
d:=-1
resolve2JosnObj(students1,d)
/*
*************解析jsonlist*************
list元素:
第0个元素: map元素:
---map[Name]的元素: 类型是string,值是 Lucy
---map[currentHight]的元素: 类型float64,值是 120
---map[Class]的元素: map元素:
------map[grade]的元素: 类型float64,值是 3
------map[classNumber]的元素: 类型float64,值是 5
第1个元素: map元素:
---map[Class]的元素: map元素:
------map[grade]的元素: 类型float64,值是 3
------map[classNumber]的元素: 类型float64,值是 6
---map[Name]的元素: 类型是string,值是 Lily
---map[currentHight]的元素: 类型float64,值是 116
*/
}
func resolve2JosnObj(objI interface{},c int){
c=c+1
switch obj:=objI.(type) { //此处[interface{}].(type) 专门用于switch的类型判断
case string:
fmt.Println("类型是string,值是",obj)
case float64:
fmt.Println("类型float64,值是",obj)
case map[string]interface{}:
fmt.Println("map元素:")
for k,vi:=range obj{
fmt.Printf("%smap[%s]的元素: ",strings.Repeat("---",c),k)
resolve2JosnObj(vi,c)
}
case []interface{}:
fmt.Println("list元素:")
for i,vi:=range obj{
fmt.Printf("%s第%d个元素: ",strings.Repeat("---",c),i)
resolve2JosnObj(vi,c)
}
default:
fmt.Println("无法判断类型,类型是",reflect.TypeOf(obj),"值是",obj)
}
}
func main() {
doMarshal()//对象转json字符串
doUnMarshal()
}
简单总结
1、结构体对象可生成json字符串,Marshal()是[]byte,需要string去转换
2、json字符串可以映射到一个struct,但仅限公共元素(大写开头);也可通用的转换到空接口interfece[],使用对应转换到需要的内容
结构体转换为JSON字符串的一个坑
通过json.Marshal来将结构体数据转换为json字符串时,需要注意结构体内成员变量的首字母大小写的问题,很容易会掉进坑里.
来看一下这个例子
package main
import (
"encoding/json"
"fmt"
)
type Student struct {
Name string
age int
}
func main() {
var s Student = Student {
Name: "xiaomo",
age: 18,
}
fmt.Printf("%+v\n", s)
res, _ := json.Marshal(s)
fmt.Println(string(res))
}
运行输出如下:
$ go run test_json.go
{Name:xiaomo age:18}
{"Name":"xiaomo"}
可以看到转换的json字符串中只包含了Name字段,age字段被忽略了.这是由于在进行json解析时,只会转换结构体能够导出的字段(首字母大写),其他字段将会被忽略.
这个机制也有个好处,可以根据实际需要,将想要导出字段的名字首字母大写,其他字段首字母小写隐藏起来即可.
以上为个人经验,希望能给大家一个参考,也希望大家多多支持golang学习网。
本篇关于《Go如何实现json字符串与各类struct相互转换》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于Golang的相关知识,请关注golang学习网公众号!
版本声明
本文转载于:脚本之家 如有侵犯,请联系study_golang@163.com删除
Go语言数据结构之双链表学习教程
- 上一篇
- Go语言数据结构之双链表学习教程
- 下一篇
- 一文搞懂Golang中iota的用法和原理
查看更多
最新文章
-
- Golang · Go教程 | 5小时前 |
- Golangreflect动态赋值方法详解
- 299浏览 收藏
-
- Golang · Go教程 | 5小时前 |
- Golang标准库与依赖安装详解
- 350浏览 收藏
-
- Golang · Go教程 | 5小时前 |
- Golang微服务熔断降级实现详解
- 190浏览 收藏
-
- Golang · Go教程 | 6小时前 |
- Go语言指针操作:*的多义与隐式&
- 325浏览 收藏
-
- Golang · Go教程 | 6小时前 |
- Golang自动扩容策略怎么实现
- 145浏览 收藏
-
- Golang · Go教程 | 6小时前 |
- Golang指针与闭包关系详解
- 272浏览 收藏
-
- Golang · Go教程 | 6小时前 |
- Golang自定义错误详解与教程
- 110浏览 收藏
-
- Golang · Go教程 | 6小时前 |
- GolangJSON读写实战教程详解
- 289浏览 收藏
-
- Golang · Go教程 | 6小时前 |
- gorun支持从标准输入执行代码吗?
- 408浏览 收藏
-
- Golang · Go教程 | 6小时前 |
- Golang环境搭建与依赖安装指南
- 368浏览 收藏
查看更多
课程推荐
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
查看更多
AI推荐
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3193次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3405次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3436次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4543次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3814次使用
查看更多
相关文章
-
- 详解如何在Go语言中循环数据结构
- 2022-12-22 406浏览
-
- 详解Golang中字符串的使用
- 2023-01-01 370浏览
-
- 一文带你搞懂Golang结构体内存布局
- 2022-12-22 125浏览
-
- 深度解密Go语言中字符串的使用
- 2022-12-24 160浏览
-
- Go实现快速生成固定长度的随机字符串
- 2023-02-24 432浏览

