在三消项目开发过程中,使用golang中的"encoding/json"包对struct结构体进行序列化,期望得到一个json string类型的字符串,但是打印的输出结果是[123 125]。

模拟示例:


package main

import (
	"encoding/json"
	"fmt"
	"runtime"
)

type user struct {
	name     string  `json: name`
	age      uint8   `json: age`
}

func main() {
	bbq := user{
		name: "bbq",
		age:  17,
	}
	jsonStr, err := json.Marshal(bbq)
	if err != nil {
		fmt.Printf("err = %v\n", err)
		return
	}
	fmt.Printf("jsonStr = %v\n", jsonStr)
}

打印结果:

期望结果:

 

 

原因分析


我们直接看下json.Marshal的代码:

可以看到,Marshal返回的值[]byte,即一个ASCII码的byte数组,[123 125]实际就是 { },[]byte类型想打印出可读的字符串,显然需要转换,我们采用string(jsonStr)的标准转换方式,打印出来的结果就是:

目前为止仅解决了打印结果不易读的问题,为什么是空json串呢,go的源码注释非常清晰,在Marshal的注释中,找到这样一段话:

 Each exported struct field becomes a member of the object,只有可导出的struct 字段才能成为json对象中的key,golang中,struct可导出的字段,是需要开头字母大写的,回过头来看项目代码,可以看到目前是小写的,

 

因为当时考虑这个结构体并不需要被外部访问,因此是小写的,没想到json.Marshal要求是大写才能转化。

 

 

解决方案


1、struct结构体中的字段名首字母大写

2、json.Marshal序列化后再做一次字符串类型转化,string()

 

示例代码修正:

package main

import (
	"encoding/json"
	"fmt"
)

type user struct {
	Name string `json: name`
	Age  uint8  `json: age`
}

func main() {
	bbq := user{
		Name: "bbq",
		Age:  17,
	}
	jsonStr, err := json.Marshal(bbq)
	if err != nil {
		fmt.Printf("err = %v\n", err)
		return
	}
	fmt.Printf("jsonStr = %s\n", string(jsonStr))
}

 

posted on 2021-11-26 18:58  Boom__Clap  阅读(768)  评论(0编辑  收藏  举报