Go 序列化json及反序列化结构体

http协议前后端的交互通过json字符串交互,在Go语言中,序列化与反序列化 需要结构体 的转化。

1、序列化为 Json 字符串

1.1 json.Marshl 序列化

func Marshal(v interface{}) ([]byte, error) 
// 定义 Student类结构体
type Student struct {
	Code    int         `json:"code"`    // 使用tag,表示对应json的字段名
	Message string      `json:"message"`
	Grades  []GradeType `json:"grades"`  // 结构体类数组
}
type GradeType struct {
	GradeClass string `json:"gradeClass"`
	Score      ScoreType
}
type ScoreType struct {
	Chinese int `json:"chinese"`
	English int `json:"english"`
}

初始化结构体,通过json.Marshal转为json字符串

func main() {
	stu := Student{
		Code:    0,
		Message: "success",
		Grades: []GradeType{
			GradeType{
				GradeClass: "一年级",
				Score: ScoreType{
					Chinese: 99,
					English: 88,
				},
			},
			GradeType{
				GradeClass: "二年级",
				Score: ScoreType{
					Chinese: 100,
					English: 98,
				},
			},
		},
	}

	fmt.Println(stu)

	s, err := json.Marshal(stu)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(s)         // [123 34 99 111 100 101 34 58 48...23 135]
	fmt.Printf("%T\n", s)  // []uint8,这里为char字节数组类型
	fmt.Println(string(s)) // 字节类型转 字符串,通过 string 直接转换
	// {"code":0,"message":"success","grades":[{"gradeClass":"一年级","Score":{"chinese":99,"english":88}},{"gradeClass":"二年级","Score":{"chinese":100,"english":98}}]}
}

1.2 Golang 优雅的输出 json字符串

为增强json字符串可读性,可调用开源的 pretty

  • 安装
go get -u github.com/tidwall/pretty
  • 用法

    Using this example:

    {"name":  {"first":"Tom","last":"Anderson"},  "age":37,
    "children": ["Sara","Alex","Jack"],
    "fav.movie": "Deer Hunter", "friends": [
        {"first": "Janet", "last": "Murphy", "age": 44}
      ]}
    

    The following code:

    result = pretty.Pretty(example)
    

    Will format the json to:

    {
      "name": {
        "first": "Tom",
        "last": "Anderson"
      },
      "age": 37,
      "children": ["Sara", "Alex", "Jack"],
      "fav.movie": "Deer Hunter",
      "friends": [
        {
          "first": "Janet",
          "last": "Murphy",
          "age": 44
        }
      ]
    }
    

    参见:https://github.com/tidwall/pretty

2、反序列化为 struct 结构体

2.1 json.Unmarshl 反序列化

需求:将json字符串转为结构体,1)预先定义json对应的结构体类型;2)调用 json.Unmarshl

func Unmarshal(data []byte, v interface{}) error 
type Student struct {
	Code    int         `json:"code"`    // 使用tag,表示对应json的字段名
	Message string      `json:"message"`
	Grades  []GradeType `json:"grades"`  // 结构体类数组
}
type GradeType struct {
	GradeClass string `json:"gradeClass"`
	Score      ScoreType
}
type ScoreType struct {
	Chinese int `json:"chinese"`
	English int `json:"english"`
}
func main() {
	// 这里反引号表示不转意,即为string类型
	resp := `{"code":0,"message":"success","grades":[{"gradeClass":"一年级","Score":{"chinese":99,"english":88}},{"gradeClass":"二年级","Score":{"chinese":100,"english":98}}]}`
	var stu Student
	err := json.Unmarshal([]byte(resp), &stu)
	if err != nil {
		log.Println(err)
	}
	log.Println(stu)
	// 2021/08/12 23:37:19 {0 success [{一年级 {99 88}} {二年级 {100 98}}]}
}

2.2 处理 http请求

	// http请求,得到json字符串 resp
  resp, err := http.Get("api")
  if err != nil{
    fmt.Println(err)
  }
  var stu Student
  err := json.Unmarshal([]byte(resp), &stu)
  if err != nil {
    log.Println(err)
  }
  log.Println(stu)

2.3 工具自动化生成 结构体

遇到http请求的多层嵌套json,莫慌,一键生成结构体,真香~

工具地址:https://mholt.github.io/json-to-go/

根据 定义好的 Json,自动生成结构体:

{
  "code": 0,
  "message": "success",
  "grades": [
    {
      "gradeClass": "一年级",
      "Score": {
        "chinese": 99,
        "english": 88
      }
    },
    {
      "gradeClass": "二年级",
      "Score": {
        "chinese": 100,
        "english": 98
      }
    }
  ]
}

如下:
在这里插入图片描述

type AutoGenerated struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Grades  []struct {
		GradeClass string `json:"gradeClass"`
		Score      struct {
			Chinese int `json:"chinese"`
			English int `json:"english"`
		} `json:"Score"`
	} `json:"grades"`
}

3、注意点

  • struct成员名字的首字母要大写
  • code的类型是int,不是string
  • 要检查Unmarshal返回的error
  • 不清楚的类型应该用 interface类型代替
  • https://gobyexample.com/json
在 Go 语言中,可以使用 `encoding/json` 包提供的 `Unmarshal` 函数将 JSON 字符串反序列化到 Go 结构体中。具体来说,可以按照以下步骤进行反序列化操作: 1. 根据 JSON 字符串的格式定义一个 Go 结构体类型。 例如,如果 JSON 字符串的格式为 `{"name": "Tom", "age": 18}`,则可以定义如下的 Go 结构体类型: ```go type Person struct { Name string `json:"name"` Age int `json:"age"` } ``` 其中,`json:"name"` 和 `json:"age"` 是结构体字段的标签,用于指定该字段在 JSON 中对应的键值。 2. 将 JSON 字符串转换成字节数组(`[]byte`)。 例如,如果 JSON 字符串为 `{"name": "Tom", "age": 18}`,则可以通过 `[]byte(jsonStr)` 将其转换成字节数组。 3. 调用 `json.Unmarshal` 函数将 JSON 字符串反序列化到 Go 结构体中。 例如,可以按照以下方式调用 `json.Unmarshal` 函数进行反序列化操作: ```go var p Person err := json.Unmarshal([]byte(jsonStr), &p) if err != nil { // 处理反序列化失败的错误 } ``` 在调用 `json.Unmarshal` 函数时,第一个参数为要反序列化JSON 字符串所对应的字节数组,第二个参数为一个指向要反序列化到的 Go 结构体对象的指针。在函数执行成功后,Go 结构体对象 `p` 就会被赋值为 JSON 字符串所对应的值。 需要注意的是,如果 JSON 字符串中的键值对与 Go 结构体中的字段不匹配,或者 JSON 字符串格式不正确,都有可能导致反序列化失败,此时需要进行错误处理。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值