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、其他

感覺其他的平時好像用到的不是特別多,可以參考一下這個文章:一葉孤舟

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章