分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 前端开发

golang json用法讲解

发布时间:2023-09-06 01:52责任编辑:林大明关键词:jsjson

简介

json格式可以算我们日常最常用的序列化格式之一了,Go语言作为一个由Google开发,号称互联网的C语言的语言,自然也对JSON格式支持很好。但是Go语言是个强类型语言,对格式要求极其严格而JSON格式虽然也有类型,但是并不稳定,Go语言在解析来源为非强类型语言时比如PHP等序列化的JSON时,经常遇到一些问题诸如字段类型变化导致无法正常解析的情况,导致服务不稳定。所以本篇的主要目的

  1. 就是挖掘Golang解析json的绝大部分能力
  2. 比较优雅的解决解析json时存在的各种问题
  3. 深入一下Golang解析json的过程
  • Golang解析JSON之Tag篇

  1. 一个结构体正常序列化过后是什么样的呢?

package mainimport ( ???"encoding/json" ???"fmt")// Product 商品信息type Product struct { ???Name ?????string ???ProductID int64 ???Number ???int ???Price ????float64 ???IsOnSale ?bool}func main() { ???p := &Product{} ???p.Name = "Xiao mi 6" ???p.IsOnSale = true ???p.Number = 10000 ???p.Price = 2499.00 ???p.ProductID = 1 ???data, _ := json.Marshal(p) ???fmt.Println(string(data))}//结果{"Name":"Xiao mi 6","ProductID":1,"Number":10000,"Price":2499,"IsOnSale":true}

  2. 何为Tag,tag就是标签,给结构体的每个字段打上一个标签,标签冒号前是类型,后面是标签名

// Product _type Product struct { ???Name ?????string ?`json:"name"` ???ProductID int64 ??`json:"-"` // 表示不进行序列化 ???Number ???int ????`json:"number"` ???Price ????float64 `json:"price"` ???IsOnSale ?bool ???`json:"is_on_sale,string"`}// 序列化过后,可以看见 ??{"name":"Xiao mi 6","number":10000,"price":2499,"is_on_sale":"false"}

  3. omitempty,tag里面加上omitempy,可以在序列化的时候忽略0值或者空值

package mainimport ( ???"encoding/json" ???"fmt")// Product _type Product struct { ???Name ?????string ?`json:"name"` ???ProductID int64 ??`json:"product_id,omitempty"` ????Number ???int ????`json:"number"` ???Price ????float64 `json:"price"` ???IsOnSale ?bool ???`json:"is_on_sale,omitempty"`}func main() { ???p := &Product{} ???p.Name = "Xiao mi 6" ???p.IsOnSale = false ???p.Number = 10000 ???p.Price = 2499.00 ???p.ProductID = 0 ???data, _ := json.Marshal(p) ???fmt.Println(string(data))}// 结果{"name":"Xiao mi 6","number":10000,"price":2499}

  4. type,有些时候,我们在序列化或者反序列化的时候,可能结构体类型和需要的类型不一致,这个时候可以指定,支持string,number和boolean

package mainimport ( ???"encoding/json" ???"fmt")// Product _type Product struct { ???Name ?????string ?`json:"name"` ???ProductID int64 ??`json:"product_id,string"` ???Number ???int ????`json:"number,string"` ???Price ????float64 `json:"price,string"` ???IsOnSale ?bool ???`json:"is_on_sale,string"`}func main() { ???var data = `{"name":"Xiao mi 6","product_id":"10","number":"10000","price":"2499","is_on_sale":"true"}` ???p := &Product{} ???err := json.Unmarshal([]byte(data), p) ???fmt.Println(err) ???fmt.Println(*p)}// 结果<nil>{Xiao mi 6 10 10000 2499 true}
  • 下面讲一讲Golang如何自定义解析JSON,Golang自带的JSON解析功能非常强悍

说明

很多时候,我们可能遇到这样的场景,就是远端返回的JSON数据不是你想要的类型,或者你想做额外的操作,比如在解析的过程中进行校验,或者类型转换,那么我们可以这样或者在解析过程中进行数据转换

实例

package mainimport ( ???"bytes" ???"encoding/json" ???"fmt")// Mail _type Mail struct { ???Value string}// UnmarshalJSON _func (m *Mail) UnmarshalJSON(data []byte) error { ???// 这里简单演示一下,简单判断即可 ???if bytes.Contains(data, []byte("@")) { ???????return fmt.Errorf("mail format error") ???} ???m.Value = string(data) ???return nil}// UnmarshalJSON _func (m *Mail) MarshalJSON() (data []byte, err error) { ???if m != nil { ???????data = []byte(m.Value) ???} ???return}// Phone _type Phone struct { ???Value string}// UnmarshalJSON _func (p *Phone) UnmarshalJSON(data []byte) error { ???// 这里简单演示一下,简单判断即可 ???if len(data) != 11 { ???????return fmt.Errorf("phone format error") ???} ???p.Value = string(data) ???return nil}// UnmarshalJSON _func (p *Phone) MarshalJSON() (data []byte, err error) { ???if p != nil { ???????data = []byte(p.Value) ???} ???return}// UserRequest _type UserRequest struct { ???Name ?string ???Mail ?Mail ???Phone Phone}func main() { ???user := UserRequest{} ???user.Name = "ysy" ???user.Mail.Value = "yangshiyu@x.com" ???user.Phone.Value = "18900001111" ???fmt.Println(json.Marshal(user))}

  

为什么要这样?

如果是客户端开发,需要开发大量的API,接收大量的JSON,在开发早期定义各种类型看起来是很大的工作量,不如写 if else 判断数据简单暴力。但是到开发末期,你会发现预先定义的方式能极大的提高你的代码质量,减少代码量。下面实例1和实例2,谁能减少代码一目了然

 实例1,if else做数据校验// UserRequest _type UserRequest struct { ???Name ?string ???Mail ?string ???Phone string}func AddUser(data []byte) (err error) { ???user := &UserRequest{} ???err = json.Unmarshal(data, user) ???if err != nil { ???????return ???} ???// ????if isMail(user.Mail) { ???????return fmt.Errorf("mail format error") ????} ???if isPhone(user.Phone) { ???????return fmt.Errorf("phone format error") ???} ???// TODO ???return} 实例2,利用预先定义好的类型,在解析时就进行判断// UserRequest _type UserRequest struct { ???Name ?string ???Mail ?Mail ???Phone Phone}func AddUser(data []byte) { ???user := &UserRequest{} ???err = json.Unmarshal(data, user) ???if err != nil { ???????return ???} ???// TODO}

  转自:http://www.cnblogs.com/yangshiyu/p/6942414.html

golang json用法讲解

原文地址:https://www.cnblogs.com/yorkyang/p/8990570.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved