GoLang中 json、map、struct 之间的相互转化
1. golang 中 json 转 struct
<1. 使用 json.Unmarshal 时,结构体的每一项必须是导出项(import field)。也就是说结构体的 key 对应的首字母必须为大写。请看下面的例子:
package commontest import (
"testing"
"encoding/json"
) type Person struct {
name string
age int
} func TestStruct2Json(t *testing.T) {
jsonStr := `
{
"name":"liangyongxing",
"age":12
}
`
var person Person
json.Unmarshal([]byte(jsonStr), &person)
t.Log(person)
}
输出的结果如下:
1
|
{ 0} |
从结果可以看出,json 数据并没有写入 Person 结构体中。结构体 key 首字母大写的话就可以,修改后:
package commontest import (
"testing"
"encoding/json"
) type Person struct {
Name string
Age int
} func TestStruct2Json(t *testing.T) {
jsonStr := `
{
"name":"liangyongxing",
"age":12
}
`
var person Person
json.Unmarshal([]byte(jsonStr), &person)
t.Log(person)
}
打印结果如下:
1
|
{liangyongxing 12} |
从以上结果我们可以发现一个很重要的信息,json 里面的 key 和 struct 里面的 key 一个是小写一个是大写,即两者大小写并没有对上。从这里我们就可以得出一个结论,要想能够附上值需要结构体中的变量名首字母大写,而在转换的 json 串中大小写都可以,即在 json 传中字段名称大小写不敏感。那么经过验证发现,在 json 中如果写成如下方式:
jsonStr := `
{
"NaMe":"liangyongxing",
"agE":12
}
`
最终结果仍然是有值的,那么就验证了我们上面的结论,json 串中对字段名大小写不敏感(不一定是首字母,这点需要注意)
<2. 在结构体中是可以引入 tag 标签的,这样在匹配的时候 json 串对应的字段名需要与 tag 标签中定义的字段名匹配,当然在 tag 中定义的名称就不需要首字母大写了,且对应的 json 串中字段名称仍然大小写不敏感,和上面的结论一致。(注意:此时结构体中对应的字段名可以不用和匹配的一致,但是也必须首字母大写,只有大写的才是可对外提供访问的)
package commontest import (
"testing"
"encoding/json"
) //这里对应的 N 和 A 不能为小写,首字母必须为大写,这样才可对外提供访问,具体 json 匹配是通过后面的 tag 标签进行匹配的,与 N 和 A 没有关系
//tag 标签中 json 后面跟着的是字段名称,都是字符串类型,要求必须加上双引号,否则 golang 是无法识别它的类型
type Person struct {
N string `json:"name"`
A int `json:"age"`
} func TestStruct2Json(t *testing.T) {
jsonStr := `
{
"name":"liangyongxing",
"age":12
}
`
var person Person
json.Unmarshal([]byte(jsonStr), &person)
t.Log(person)
}
这样输出的结果如下:
1
|
{liangyongxing 12} |
当然,你也可以再做一个实验,验证 tag 标签中对应的字段名称大小写不敏感,这里就不做冗余介绍了。
2. golang 中 struct 转 json 串
1 package commontest
2
3 import (
4 "testing"
5 "encoding/json"
6 )
7
8 func TestStruct2Json(t *testing.T) {
9 p := Person{
10 Name: "liangyongxing",
11 Age: 29,
12 }
13
14 t.Logf("Person 结构体打印结果:%v", p)
15
16 //Person 结构体转换为对应的 Json
17 jsonBytes, err := json.Marshal(p)
18 if err != nil {
19 t.Fatal(err)
20 }
21 t.Logf("转换为 json 串打印结果:%s", string(jsonBytes))
22 }
打印结果如下所示:
1
2
3
4
|
/usr/local/ go /bin/ go test -v commontest -run ^TestStruct2Json$ struct2json_test. go :14: Person 结构体打印结果:{liangyongxing 29} struct2json_test. go :21: 转换为 json 串打印结果:{ "name" : "liangyongxing" , "age" :29} ok commontest 0.006s |
3. golang 中 json 转 map
package commontest import (
"testing"
"encoding/json"
) func TestJson2Map(t *testing.T) {
jsonStr := `
{
"name":"liangyongxing",
"age":12
}
`
var mapResult map[string]interface{}
//使用 json.Unmarshal(data []byte, v interface{})进行转换,返回 error 信息
if err := json.Unmarshal([]byte(jsonStr), &mapResult); err != nil {
t.Fatal(err)
}
t.Log(mapResult)
}
打印结果信息如下:
1
2
3
|
/usr/local/ go /bin/ go test -v commontest -run ^TestJson2Map$ json2map_test. go :19: map [name:liangyongxing age:12] ok commontest 0.007s |
4. golang 中 map 转 json 串
package commontest import (
"testing"
"encoding/json"
) func TestMap2Json(t *testing.T) {
mapInstance := make(map[string]interface{})
mapInstance["Name"] = "liang637210"
mapInstance["Age"] = 28
mapInstance["Address"] = "北京昌平区" jsonStr, err := json.Marshal(mapInstance) if err != nil {
t.Fatal(err)
} t.Logf("Map2Json 得到 json 字符串内容:%s", jsonStr)
}
打印结果如下:
1
2
3
|
/usr/local/ go /bin/ go test -v commontest -run ^TestMap2Json$ map2json_test. go :20: Map2Json 得到 json 字符串内容:{ "Address" : "北京昌平区" , "Age" :28, "Name" : "liang637210" } ok commontest 0.008s |
5. golang 中 map 转 struct
这个转换网上有比较完整的项目,已经上传到对应的 github 上了,需要下载之后使用:
1
|
$ go get github.com /goinggo/mapstructure |
之后我们就可以直接使用它提供的方法将 map 转换为 struct,让我们直接上代码吧
package commontest import (
"testing"
"github.com/goinggo/mapstructure"
) func TestMap2Struct(t *testing.T) {
mapInstance := make(map[string]interface{})
mapInstance["Name"] = "liang637210"
mapInstance["Age"] = 28 var person Person
//将 map 转换为指定的结构体
if err := mapstructure.Decode(mapInstance, &person); err != nil {
t.Fatal(err)
}
t.Logf("map2struct后得到的 struct 内容为:%v", person)
}
打印结果如下:
1
2
3
|
/usr/local/go/bin/go test - v commontest -run ^TestMap2Struct$ map2struct_test.go:18: map2struct后得到的 struct 内容为:{liang637210 28} ok commontest 0.009s |
6. golang 中 struct 转 map
1 package commontest
2
3 import (
4 "testing"
5 "reflect"
6 )
7
8 type User struct {
9 Id int `json:"id"`
10 Username string `json:"username"`
11 Password string `json:"password"`
12 }
13
14 func Struct2Map(obj interface{}) map[string]interface{} {
15 t := reflect.TypeOf(obj)
16 v := reflect.ValueOf(obj)
17
18 var data = make(map[string]interface{})
19 for i := 0; i < t.NumField(); i++ {
20 data[t.Field(i).Name] = v.Field(i).Interface()
21 }
22 return data
23 }
24
25 func TestStruct2Map(t *testing.T) {
26 user := User{5, "zhangsan", "password"}
27 data := Struct2Map(user)
28 t.Logf("struct2map得到的map内容为:%v", data)
29 }
打印结果如下:
1
2
3
|
/usr/local/ go /bin/ go test -v commontest -run ^TestStruct2Map$ struct2map_test. go :28: struct2map得到的 map 内容为: map [Id:5 Username:zhangsan Password:password] ok commontest 0.007s |
GoLang中 json、map、struct 之间的相互转化的更多相关文章
- Go_14:GoLang中 json、map、struct 之间的相互转化
1. golang 中 json 转 struct <1. 使用 json.Unmarshal 时,结构体的每一项必须是导出项(import field).也就是说结构体的 key 对应的首字母 ...
- map json 字符串 对象之间的相互转化
1.对象与字符串之间的互转 将对象转换成为字符串 String str = JSON.toJSONString(infoDo); 字符串转换成为对象 InfoDo infoDo = JSON.pars ...
- golang中json包序列化与反序列化
package main import ( "encoding/json" "fmt" "reflect" ) type Info stru ...
- golang中string以及slice之间的一些问题
好记性不如烂笔头o_O slice切片不会开辟新的空间 a := []int{0,1,2,3} b := make([]int, 8) b = a[:] b[2] = 9 fmt.Println(a) ...
- python中json与dict之间转换
Python之dict(或对象)与json之间的互相转化 在Python语言中,json数据与dict字典以及对象之间的转化,是必不可少的操作. 在Python中自带json库.通过import js ...
- golang中,map作为函数参数是如何传递的
当你声明一个map的时候: m := make(map[int]int) 编译器会调用 runtime.makemap: // makemap implements a Go map creation ...
- Golang中的Map(集合)
Map 是一种无序的键值对的集合.Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值. Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它.不过,Map 是无 ...
- golang中json格式化自定义日期格式
go 的time.Time,在json序列化是默认 2006-01-02T15:04:05Z07:00 的格式,十分不便, encoding/json包在序列化和反序列化的时候分别调用encode.g ...
- golang中的map
1. 声明与初始化 // map的声明与初始化 userInfo := map[string]string{"name": "马亚南", "age&q ...
随机推荐
- JavaQuery
1.初识jQuery <!DOCTYPE html> <html> <head lang="en"> <meta charse ...
- python opencv3 显示一张图片
git:https://github.com/linyi0604/Computer-Vision # coding:utf8 import cv2 """ 显示一张图像 ...
- 阿里云腾讯云服务器ubuntu多域名配置
1.将域名A记录解析到服务器的公网 IP 地址,把www也添加A记录到公网ip 2.ubuntu系统修改hosts文件,hosts文件目录为/etc/hosts,可以用vim编辑 sudo vim ...
- SPOJ8791 DYNALCA LCT
考虑\(LCT\) 不难发现,我们不需要换根... 对于操作\(1\),\(splay(u)\)然后连虚边即可 对于操作\(3\),我们可以先\(access(u)\),然后再\(access(v)\ ...
- [BZOJ2815][ZJOI2012]灾难(拓扑排序/支配树)
支配树目前只见到这一个应用,那就不独分一类,直接作为拓扑排序题好了. 每个点向所有食物连边,定义fa[x]为x的支配点,即离x最近的点,满足若fa[x]灭绝,则x也要灭绝. 这样,将fa[x]向x连边 ...
- 洛谷.4252.[NOI2006]聪明的导游(提答 直径 随机化)
题目链接 随机化 暴力: 随便从一个点开始DFS,每次从之前得到的f[i]最大的子节点开始DFS.f[i]为从i开始(之前)能得到的最大答案. 要注意的是f[i]应当有机会从更小的答案更新, 9.10 ...
- 【平面图最小割】BZOJ2007-[NOI2010]海拔
[题目大意] 城市被东西向和南北向的主干道划分为n×n个区域,包括(n+1)×(n+1)个交叉路口和2n×(n+1)条双向道路.现得到了每天每条道路两个方向的人流量.每一个交叉路口都有海拔,每向上爬h ...
- 推荐C#网站、书籍、资源
推荐博客: 极简的随笔 http://www.cnblogs.com/guwei4037/p/3499135.html 见证大牛成长之路的专栏 http://blog.csdn.net/shanyon ...
- 电子数据识别软件ABBYY FineReader
ABBYY 是一家俄罗斯软件公司,在文档识别,数据捕获和语言技术的开发中居世界领先地位.其获奖产品 FineReader OCR 软件可以把静态纸文件和 PDF 文件转换成可管理的电子数据,可以大大节 ...
- weblogic安装使用: Could not Create the Java Virtual Machine
第一次使用weblogic,完全不明白是怎么一回事!找安装包花了大把时间!找到了不知道怎么安装 -- _ --||| 找了一篇安装文档<weblogic 安装部署手册.doc>, 位于:[ ...