数据类型中转json的函数
基本数据转json
Marshal使用以下与类型相关的默认编码:
布尔值编码为JSON布尔值。
浮点数、整数和数字值编码为JSON数字。
字符串值编码为JSON字符串,强制为有效的UTF-8;
用Unicode替换符文替换无效字节。
这样JSON就可以安全地嵌入到HTML
map转JSON
type user struct {
Username string `json:"name"`
Userid string `json:"id"`
Age int `json:"age"`
}
func main() {
jsonS()
}
func jsonS() {
//Go的标准包encoding/json对JSON的支持
//JSON编码即将Go数据类型转换为JSON字符串
m := make(map[string]interface{})
m["name"] = "小花"
m["age"] = 18
u1 := user{
Username: "小红",
Userid: "1024",
Age: 10,
}
marshal, err := json.Marshal(m)
i, _ := json.Marshal(u1)
fmt.Println(i)
fmt.Println(string(i))
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println(string(marshal))
}
运行结果:
结构体转json
注意:如果结构体中的字段以小写字母开头,那么结构体在抓换 json时不会解析该字段:
如果结构体转json时定义的结构体没有指定转换json时的字段别名,那么结构体转json后会按照结构体字段名显示
例如:
type DogW struct {
Name string
Age int
color string
}
type CatC struct {
name string
age int
color string
}
type HenH struct {
Name string `json:"name"`
Age int `json:"age"`
Color string `json:"color"`
}
func main() {
d := DogW{
Name: "汪汪",
Age: 2,
color: "黄",
}
c := CatC{
name: "喵喵",
age: 3,
color: "狸花",
}
h := HenH{
Name: "咯咯哒",
Age: 1,
Color: "黄红",
}
indent, err := json.MarshalIndent(d, "", "")
if err != nil {
fmt.Println("转换失败")
return
}
fmt.Println("Dog结构体转json--", string(indent))
marshalIndent, err := json.MarshalIndent(c, "", " ")
fmt.Println("Cat结构体转json--", string(marshalIndent))
i, err := json.MarshalIndent(h, "", "")
fmt.Println("Hen结构体转json--", string(i))
}
将json输出格式化,以便于阅读
u1 := user{
Username: "小红",
Userid: "1024",
Age: 10,
}
//将json输出 格式化
// MarshalIndent类似于Marshal,但使用缩进来格式化输出。
//输出中的每个JSON元素将在以prefix开头的新行开始
//根据缩进嵌套,后跟一个或多个缩进副本。
indent, err := json.MarshalIndent(u1, "", " ")
fmt.Println(string(indent))
结构体匿名字段转Json
type DogW struct {
DName string
DAge int
DColor string
CatC //匿名字段
}
type CatC struct {
Name string
Age int
Color string
}
func main() {
d := DogW{
DName: "汪汪",
DAge: 2,
DColor: "黄",
CatC: CatC{
Name: "喵喵",
Age: 3,
Color: "狸花",
},
}
indent, err := json.MarshalIndent(d, "", "")
if err != nil {
fmt.Println("转换失败")
return
}
fmt.Println("Dog结构体转json--", string(indent))
}
注意:json包在解析匿名字段时,会将匿名字段的字段当成该结构体的字段处理
另外,如果嵌套的匿名字段的属性跟外部结构体的字段名一致,那么在转json后 只会显示外部的字段比如下面的代码:
type DogW struct {
Name string
Age int
Color string
CatC //匿名字段
}
type CatC struct {
Name string
Age int
Color string
}
func main() {
d := DogW{
Name: "汪汪",
Age: 2,
Color: "黄",
CatC: CatC{
Name: "喵喵",
Age: 3,
Color: "狸花",
},
}
indent, err := json.MarshalIndent(d, "", "")
if err != nil {
fmt.Println("转换失败")
return
}
fmt.Println("Dog结构体转json--", string(indent))
这里就有许多情况—下面的情况就很好玩
type DogW struct {
Name string
Age int
color string
CatC //匿名字段
}
type CatC struct {
Name string
Age int
Color string
}
func main() {
d := DogW{
Name: "汪汪",
Age: 2,
color: "黄",
CatC: CatC{
Name: "喵喵",
Age: 3,
Color: "狸花",
},
}
indent, err := json.MarshalIndent(d, "", "")
if err != nil {
fmt.Println("转换失败")
return
}
fmt.Println("Dog结构体转json--", string(indent))
结果:
Marshal()函数源码
func Marshal(v any) ([]byte, error) {
e := newEncodeState()
defer encodeStatePool.Put(e)
err := e.marshal(v, encOpts{escapeHTML: true})
if err != nil {
return nil, err
}
buf := append([]byte(nil), e.Bytes()...)
return buf, nil
}
Marshal()函数只有在转换成功的时候才会返回数据,在转换的过程中需要注意如下几点。• JSON对象只支持string作为key,所以要编码一个map,必须是map[string]T这种类型(T是Go语言中的任意类型)。• channel、complex和function是不能被编码成JSON的。• 指针在编码的时候会输出指针指向的内容,而空指针会输出null。
json转Go中数据类型
//结构体
type CatC struct {
Name string `json:"name"`
Age int `json:"age"`
Color string `json:"color"`
}
//json解析
//JSON解析就是将JSON转换为Go数据类型。
func UNJSON() {
d := DogW{
Name: "dog",
Age: 2,
color: "黄",
CatC: CatC{
Name: "喵喵",
Age: 3,
Color: "狸花",
},
}
//转换成json
indent, err := json.MarshalIndent(d, "", " ")
if err != nil {
return
}
fmt.Println(string(indent))
var dog DogW
//json转go类型
err = json.Unmarshal(indent, &dog)
fmt.Println(dog)
data := `[{"level":"debug","Msg":"File:\"test.txt\"NOT FOUND"},` + `{"Level":"","msg":"Logic error"}]`
Catc := `{"Name":"狸花猫","Age":2,"Color":"梨花"}`
Catd := `{"name":"狸花猫","age":2,"color":"梨花"}`
var mapM []map[string]string
json.Unmarshal([]byte(data), &mapM)
var catc CatC
var catd CatC
json.Unmarshal([]byte(Catc), &catc)
json.Unmarshal([]byte(Catd), &catd)
fmt.Println(mapM)
fmt.Println(catc)
fmt.Println(catd)
}
func main() {
UNJSON()
}
注意json.Unmarshal([]byte(data), &mapM)中第二个参数要取址才会将解析出来的数据赋值给 对象mapM
JSON可以转换成结构体。同编码一样,json包是通过反射机制来实现解码的,因此结构体必须导出所转换的字段,不导出的字段不会被json包解析。另外解析时不区分大小写。
json转结构体时也是支持json标签的:
结果如下:
{
"Name": "dog",
"Age": 2,
"name": "喵喵",
"age": 3,
"color": "狸花"
}
{dog 2 {喵喵 3 狸花}}
[map[Msg:File:"test.txt"NOT FOUND level:debug] map[Level: msg:Logic error]]
{狸花猫 2 梨花}
{狸花猫 2 梨花}
如果在换转换时有匿名字段—>>
在解码JSON时,如果找不到字段,则查找字段的字段
比如下面的例子:
type CatCC struct {
Name string `json:"name"`
Age int `json:"age"`
Color string `json:"color"`
}
type DogWW struct {
DName string
DAge int
Dcolor string
CatCC //匿名字段
}
func main() {
//UNJSON()
TestUnjson()
}
func TestJson() {
Dogw := `{"DName":"dogdog","DAge":22,"Dcolor":"Black","CatCC":{"Name":"喵miaomiao喵","Age":3,"Color":"狸花"}}`
Dogww := `{"Name":"dogdog","Age":22,"color":"Red","CatCC":{"Name":"喵miaomiao喵","Age":3,"Color":"狸花"}}`
var dog *DogWW
var dogw *DogWW
json.Unmarshal([]byte(Dogw), dog)
json.Unmarshal([]byte(Dogww), dogw)
fmt.Println(&dog)
fmt.Println(&dogw)
}
运行结果:
结构体没有字段时,会使用结构体字段对应的类型默认值
这也体现了 结构体中嵌套了匿名结构体----继承
如果结构体属性中没有值,那么我们可以通过加入 json 字段来将空的值给忽略:
type User struct {
Name string `json:"name"`
Email string `json:"email"` //加上omitempty标签,表示输出会将空值忽略掉,此时暂不加,看结果
Hobby []string `json:"hobby"`
}
func omitemptyDemo1() {
// 当 struct 中的字段没有值Email,Hobby 字段时
us := User{
Name: "Gavin",
}
b, err := json.Marshal(us)
if err != nil {
fmt.Printf("json.Marshal failed, err:%v\n", err)
return
}
fmt.Printf("str:%s\n", b)
}
运行结果:
{"name":"Jack","email":"","hobby":null}
str:{"name":"Jack","email":"","hobby":null}
加入omitempty标签后:
type User struct {
Name string `json:"name"`
Email string `json:"email,omitempty"` //加上omitempty标签,表示输出会将空值忽略掉
Hobby []string `json:"hobby,omitempty"`
}
//运行结果 str:{"name":"Jack"}
json转嵌套结构体
type Pig struct {
PName string `json:"pname"`
Age int `json:"age"`
}
type Animals struct {
Types string
Group []Pig
}
func main() {
var r Animals
s := `{"Types":"猪","Group":[{"pname":"大猪","age":3},{"pname":"小猪仔","age":1}]}`
err := json.Unmarshal([]byte(s), &r)
if err != nil {
fmt.Print(err)
}
fmt.Println(r)
}