对于结构体大家都很熟悉,是一种自定义类型,可以将不同类型的同属于这个类的属性(成员变量)集合在一起,换句话说这些成员变量属于键值对,那么这种也就是常见的json格式,我们来看下如何将结构体转成json格式的字符串。

Marshal转字符串

package mainimport ("encoding/json""fmt"
)type Person struct {Name  stringTall  float32Hobby string
}func main() {//实例化的时候要注意,最后的逗号不能省略p := Person{Name: "Tony", Tall: 173.5, Hobby: "Reading",}fmt.Println(p) //{Tony 173.5 Reading}json_p, err := json.Marshal(p)fmt.Printf("%T,%s,%v", string(json_p), string(json_p), err)//string,{"Name":"Tony","Tall":173.5,"Hobby":"Reading"},<nil>
}

如果结构体成员变量名称的首字母是小写的话,会发生什么情况?

package mainimport ("encoding/json""fmt"
)type Person struct {Name    stringTall    float32Hobby   stringaddress string //首字母小写Sex     string
}func main() {//实例化的时候要注意,最后的逗号不能省略p := Person{Name: "Tony", Tall: 173.5, Hobby: "Reading", address: "湖南省", Sex: "男",}fmt.Println(p) //{Tony 173.5 Reading 湖南省 男}json_p, err := json.Marshal(p)fmt.Printf("%T,%s,%v", string(json_p), string(json_p), err)//string,{"Name":"Tony","Tall":173.5,"Hobby":"Reading","Sex":"男"},<nil>
}

我们发现这个address成员变量没有转换成功,没有出现,那说明如果需要转成json,首字母必须大写。然后我们反过来将json字符串转换成结构体,看下有什么变化。

var out Person
json.Unmarshal(json_p, &out)
fmt.Printf("%T,%#v,%v", out, out, err)
//main.Person,main.Person{Name:"Tony", Tall:173.5, Hobby:"Reading", address:"", Sex:"男"},<nil>

address的内容是空,如果是整型,内容是0,这验证了,如果外部需获取成员变量的情况,首字母需大写。

结构体嵌套

结构体是多个类型的集合,所以除了基本类型之外,自定义类型肯定也是可以一起放在里面,无差别对待使用,而结构体里面的结构体可以是指针也可以不是指针,不过建议使用指针的表示形式,这个只是一个内存地址而已,效率要快。

package mainimport ("encoding/json""fmt"
)type Person struct {Name    stringTall    float32Hobby   stringaddress string //首字母小写Sex     stringGame    *Game //指向一个玩过什么游戏的一个结构体,也可以不使用指针,指针要快
}
type Game struct {Name1 stringName2 string
}func main() {//实例化的时候要注意,最后的逗号不能省略p := Person{Name: "Tony", Tall: 173.5, Hobby: "Reading", address: "湖南省", Sex: "男",}//指针用法game := new(Game)game.Name1 = "星际争霸"game.Name2 = "王者荣耀"p.Game = game/*非指针用法game := Game{Name1: "王者荣耀", Name2: "魔兽世界"}p.Game = game*/json_p, err := json.Marshal(p)if err != nil {fmt.Println("转换json字符串失败!")}fmt.Printf("%T,%s", string(json_p), string(json_p))
}
//string,{"Name":"Tony","Tall":173.5,"Hobby":"Reading","Sex":"男","Game":{"Name1":"星际争霸","Name2":"王者荣耀"}}

结构体接口

看过Go语言进阶,interface接口,socket套接字这篇文章的伙伴就应该知道,其中的 tester = p 就是将类型赋值给了接口。我们现在来改造这个结构体,使其变得更加的通用,也就是说不管什么类型都可以,而不是指定了string就只能是字符串类型。

type Person struct {Name    interface{}Tall    interface{}Hobby   interface{}address interface{} //首字母小写Sex     interface{}Game    interface{}
}

然后我们将那个Hobby爱好,原来是字符串的,我们使用整型为其赋值,试下:

p := Person{Name: "Tony", Tall: 173.5, Hobby: 123, address: "湖南省", Sex: "男",
}
//string,{"Name":"Tony","Tall":173.5,"Hobby":123,"Sex":"男","Game":{"Name1":"星际争霸","Name2":"王者荣耀"}}

OK,没有问题!
所有类型全部替换成interface{}空接口,因为在go语言中的每一种类型都实现了该接口,换句话说就是任何其他类型的数据都可以赋值给interface{}类型

Unmarshal字符串转结构体

json字符串转化成结构体的话,关键是json的字符串格式要严格符合规范,如:双引号需要反斜杠进行转义操作,括号要匹配不能缺失等。Unmarshal两个参数,一个是字节数组,另一个对空结构体取地址即可。

package mainimport ("encoding/json""fmt"
)type Person struct {Name    interface{}Tall    interface{}Hobby   interface{}address interface{} //首字母小写Sex     interface{}Game    interface{}
}func main() {data := "{\"Name\":\"Tony\",\"Tall\":173.5,\"Hobby\":\"Reading\",\"Sex\":\"男\",\"Game\":{\"Name1\":\"星际争霸\",\"Name2\":\"王者荣耀\"}}"s := []byte(data)p := Person{}err := json.Unmarshal(s, &p)if err != nil {fmt.Println(err)}fmt.Printf("%T,%#v", p, p)
}
/*
main.Person,main.Person{Name:"Tony", Tall:173.5, Hobby:"Reading", address:interface {}(nil), Sex:"男", Game:map[string]interface {}{"Name1":"星际争霸", "Name2":"王者荣耀"}}
*/

我们通过反射看下它们各自的数据类型:

package mainimport ("encoding/json""fmt""reflect"
)type Person struct {Name    interface{}Tall    interface{}Hobby   interface{}address interface{} //首字母小写Sex     interface{}Game    interface{}
}func main() {data := "{\"Name\":\"Tony\",\"Tall\":173.5,\"Hobby\":\"Reading\",\"Sex\":\"男\",\"Game\":{\"Name1\":\"星际争霸\",\"Name2\":\"王者荣耀\"}}"s := []byte(data)p := Person{}printType(&p)err := json.Unmarshal(s, &p)if err != nil {fmt.Println(err)}fmt.Println("Unmarshal之后的结果")printType(&p)
}
func printType(p *Person) {nameType := reflect.TypeOf(p.Name)tallType := reflect.TypeOf(p.Tall)hobbyType := reflect.TypeOf(p.Hobby)addressType := reflect.TypeOf(p.address)sexType := reflect.TypeOf(p.Sex)gameType := reflect.TypeOf(p.Game)fmt.Println("nameType:", nameType)fmt.Println("ageType:", tallType)fmt.Println("highType:", hobbyType)fmt.Println("sexType:", addressType)fmt.Println("classType:", sexType)fmt.Println("testType:", gameType)
}
/*
nameType: <nil>
ageType: <nil>
highType: <nil>
sexType: <nil>
classType: <nil>
testType: <nil>
Unmarshal之后的结果
nameType: string
ageType: float64
highType: string
sexType: <nil>
classType: string
testType: map[string]interface {}
*/

最后还可以指定别名,大家可以试下:

Name    string `json:"name"`

这个就是用name代替Name

Go语言进阶,结构体与json字符串格式的互相转换相关推荐

  1. c语言将结构体转换为字符串,[流畅的 C]C语言将结构体转化为字符串

    [流畅的 C] C语言将结构体转化为字符串 本文并非标题的具体实现.而是提供一种编程方式,习惯,一种探讨. 本文有一点点门槛,有 socket,开源协议栈学习/开发经验者阅读更佳. Overview ...

  2. go语言中结构体与json

    go语言中使用Marshal函数实现结构体json化,需要有一下两点注意 因为json化是在其他函数中完成,因此需要将结构体中的成员大写,这样才能在生成的结构体中有对应的元素 在结构体后面,如果有需要 ...

  3. C语言——把结构体数据封装成TLV格式的数据

    功能描述: typedef struct {     unsigned char ucPort;     pid_t stPid; }TEST_INFO_S; 结构体TETS_INFO_S内有两个变量 ...

  4. C 语言编程 — 结构体的数据类型转换

    目录 文章目录 目录 数组类型强制类型转换为结构体 结构体之间的强制类型转换 数组类型强制类型转换为结构体 先看一个例子: #include <stdio.h>int main(void) ...

  5. c 语言结构体类型转换,C 语言编程 — 结构体的数据类型转换

    目录 数组类型强制类型转换为结构体 先看一个例子: #include int main(void) { unsigned char arr[] = "0123456789abcdefghij ...

  6. c语言结构体定义字符串数组,C语言,结构体中字符串的声明(采用字符指针还是字符数组)...

    结构体中,字符串选项是用字符数组表示好,还是用字符指针表示好? typedef struct person{ char *name; int age; char sex[6]; }: 该结构体中nam ...

  7. Go语言中结构体打Tag是什么意思?

    前言 哈喽,大家好,我是asong.今天想与大家分享Go语言中结构体标签是怎么使用的,以及怎样定制自己的结构体标签解析. 大多数初学者在看公司的项目代码时,看到的一些结构体定义会是这样的: type ...

  8. 【Golang第8章:面向对象编程】Go语言的结构体是什么,怎么声明;Golang方法的调用和声明;go语言面向对象实例,go语言工厂模式;golang面向对象的三大特性:继承、封装、多态

    介绍 这个是在B站上看边看视频边做的笔记,这一章是Glang面向对象编程 这一章内容较多,内容有Go语言的结构体是什么,怎么声明:Golang方法的调用和声明:go语言面向对象实例,go语言工厂模式: ...

  9. Go语言中结构体打 Tag 是什么意思?

    前言 哈喽,大家好,我是asong.今天想与大家分享Go语言中结构体标签是怎么使用的,以及怎样定制自己的结构体标签解析. 大多数初学者在看公司的项目代码时,看到的一些结构体定义会是这样的: type ...

最新文章

  1. C++11 开启多线程
  2. Redis的二八定律
  3. Object类toString()和equals()方法剖析
  4. Apache增加SSL功能的步骤
  5. java计算八皇后_八皇后java算法
  6. win7系统,virtualBox导入centos7.3报错
  7. Android7.0预置带so的apk
  8. adroid intent使用
  9. C语言中数字转换成字符,c语言中数字转换成字符串的方法
  10. 拼多多微信登录服务器请求失败,拼多多管理后台登不上怎么回事?有何功能?...
  11. 适合APP的开发模式——敏捷开发
  12. 高等数学|微积分(上)知识点总结
  13. 怎么屏蔽计算机集成声卡,win10系统主板集成声卡关闭的设置方案
  14. windows 编译n2n
  15. 从多个Word文档中批量取值,整理到Excel表中。
  16. IMX6ULL 串口5修改
  17. 文字折叠特效 html+css
  18. 大数据开发方向分享:春招获蚂蚁金服、拼多多、华为(终端)、远景能源、华泰证券等offer
  19. hdu1002 a+bII 大数相加
  20. CLA not signed yet

热门文章

  1. 计算机的usn插口无法读取,USB3.0还缺谁 解决主板插槽不健全方案
  2. 越狱Season 1-Episode 14: The Rat
  3. 图书信息管理系统(数据结构顺序表,c语言版)
  4. java学习书籍推荐
  5. 新包青天 片尾曲 参人生哲理
  6. java 中的 while和 do...while语句的区别
  7. 电锯惊魂—经典的语言
  8. java rgb十六进制数据转图片
  9. UVA 10118 简单DP
  10. 代码随想录训练营day27