文章目錄
1、json
1、Marshal:對象轉換成json串
1、規則
- 在tag裏面用
json:"name"
可以定義別名,這個正常是爲了保證外部進來的小寫,而對外聲明的首字母大寫(非私有) - tag中有
json:"-"
的數據不會被轉出,如果帶別名的-是會被正常轉出的,比如說:json:"value,-"
- 結構體的私有屬性不能被轉換
- 時間轉換之後會採用默認格式
- 通過自定義方法可以實現時間格式的自定義,下面詳細講
- 在字段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、其他
感覺其他的平時好像用到的不是特別多,可以參考一下這個文章:一葉孤舟