文章目录
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、其他
感觉其他的平时好像用到的不是特别多,可以参考一下这个文章:一叶孤舟