Go官方包:encodinng常用方法

1、json

1、Marshal:对象转换成json串

1、规则

  1. 在tag里面用json:"name"可以定义别名,这个正常是为了保证外部进来的小写,而对外声明的首字母大写(非私有)
  2. tag中有json:"-"的数据不会被转出,如果带别名的-是会被正常转出的,比如说:json:"value,-"
  3. 结构体的私有属性不能被转换
  4. 时间转换之后会采用默认格式
  5. 通过自定义方法可以实现时间格式的自定义,下面详细讲
  6. 在字段tag中加上,omitempty,如果是空或者默认值不会被转换出去

转换的结果如下:
在这里插入图片描述

2、测试代码

看一下测试代码:

	/*
	 *  @Author : huangzj
	 *  @Time : 2020/3/27 15:38
	 *  @Description:
	 */	
	package main
	import (
		"encoding/json"
		"fmt"
		"time"
	)
	
	type Time time.Time
	
	const (
		timeFormart = "2006-01-02 15:04:05"
	)
	
	type json1 struct {
		Name      string    `json:"name"`       //测试一下别名
		Value     string    `json:"value,-"`    //测试一下,有别名也有 - 能被转换
		Value1    string    `json:"-"`          //测试一下,只有 - 能被转换
		method1   string    `json:"method1"`    //测试一下私有属性不能被转换
		Now       time.Time `json:"now"`        //测试一下时间字段可否被转换
		Now1      Time      `json:"now1"`        //自定义时间转换的格式
		Age       int       `json:",omitempty"` //测试一下 omitempty 值为空不能被转换
		AgeString string    `json:",omitempty"` //测试一下字符串 omitempty 值为空 不能被转换
		Length    int       `json:",String"`    //测试一下tag里面带有string的自动转换
	}
	
	func jsonTest() {
		j := json1{
			Name:    "name",
			Value:   "value",
			Value1:  "value1",
			method1: "method1",
			Now:     time.Now(),
			Now1:    Time(time.Now()),
			Age:     0,
			Length:  24,
		}
	
		b, err := json.Marshal(j)
		if err != nil {
			panic(err.Error())
		}
	
		fmt.Print(string(b))
	
	}
	
	func (t Time) MarshalJSON() ([]byte, error) {
		b := make([]byte, 0, len(timeFormart)+2)
		b = append(b, '"')
		b = time.Time(t).AppendFormat(b, timeFormart)
		b = append(b, '"')
		return b, nil
	}
	
	func (t Time) String() string {
		return time.Time(t).Format(timeFormart)
	}

3、时间自定义格式转换

默认的时间格式转换是类似2019-07-01T20:08:23.000000028+08:00这种的格式,这边的话,如果想要自定义的需要自定义类型和方法,具体参考文章:小风疏雨

1、定义time别名和时间格式化字符串

	type Time time.Time

	const (
		timeFormart = "2006-01-02 15:04:05"
	)

2、实现MarshalJSON接口

这个是encoding包的接口,这边需要实现这个接口来实现自定义时间格式化, 具体代码如下:


	func (t Time) MarshalJSON() ([]byte, error) {
		b := make([]byte, 0, len(timeFormart)+2)
		b = append(b, '"')
		b = time.Time(t).AppendFormat(b, timeFormart)
		b = append(b, '"')
		return b, nil
	}

3、实现string接口

这边需要实现string接口,保证输出的是我们需要的格式

	func (t Time) String() string {
		return time.Time(t).Format(timeFormart)
	}

4、数据声明的类型

这边数据声明的类型应该是我们自定义的time.Time别名的类型
在这里插入图片描述
然后直接调用json.Marshal方法就可以按照我们的设定输出自定义的时间格式。

4、多层结构的转换

这边还测试了一下,在json1的结构体中加入一个自定义的结构体,可以转换出来,规则和上方类型


2、Unmarshal:字符串转对象

1、常规转换

看一下代码。我们这边使用json.unmarshall方法对json字符串进行转换为结构体

结构体

	type Person struct {
		Id       int64  `json:"id"`
		Name     string `json:"name"`
	}

转换代码

	func jsonTest1() {
	src := `{"id":5,"name":"xiaoming"}`
	p := new(Person)
	err := json.Unmarshal([]byte(src), &p)
	if err != nil {
		panic(err.Error())
	}
}

结果正常。

2、转换为map

如果我没有定义结构体,而只是想把它转换成map,要怎么处理,因为key只支持string类型,所以这边定义的map也必须是 map[string]interface 类型的。看一下代码(实体如上):

	func jsonTest1() {
		src := `{"id":5,"name":"xiaoming"}`
		p := new(Person)
		err := json.Unmarshal([]byte(src), &m)
		if err != nil {
			panic(err.Error())
		}
	}

其实map和结构体很类似,结构体的属性更加明确,但是本质上,他们应该是一致的

3、时间转换

1、定义time别名和时间格式化字符串

	type Time time.Time

	const (
		timeFormart = "2006-01-02 15:04:05"
	)

2、实现UnmarshalJSON接口

这个也是encoding包对外的接口

	func (t *Time) UnmarshalJSON(data []byte) (err error) {
	now, err := time.ParseInLocation(`"`+timeFormart+`"`, string(data), time.Local)
	*t = Time(now)
	return
}

3、实现string方法

因为这边是需要输出,所以要实现string方法,不然就是一串时间戳


	func (t Time) String() string {
		return time.Time(t).Format(timeFormart)
	}

4、转换

	//实体
	type Person struct {
		Id       int64  `json:"id"`
		Name     string `json:"name"`
		Birthday Time   `json:"birthday"`
	}
	
	//转换方法
	func jsonTest1() {
		src := `{"id":5,"name":"xiaoming","birthday":"2016-06-30 16:09:51"}`
		p := new(Person)
		err := json.Unmarshal([]byte(src), &p)
		if err != nil {
			panic(err.Error())
		}
	}

2、其他

感觉其他的平时好像用到的不是特别多,可以参考一下这个文章:一叶孤舟

发布了117 篇原创文章 · 获赞 15 · 访问量 5601

猜你喜欢

转载自blog.csdn.net/qq_34326321/article/details/105143511