由类型引出的interface处理
type 类型名字 底层类型
type City string // 城市
type Province string // 省份
虽然两个类型的底层数据类型相同,但是它们是两种不同的数据类型。它们是不能用来直接进行比较或者运算的。需要显示转换。
定义新类型的好处是,我们可以给这个类型添加方法集,表示这个类型定义的变量具有一系列行为。例如:
type City string
func (c City) String() string {
return fmt.Sprintf("%s", c)
}
许多类型都会定义String方法,因为当使用fmt包的打印方法时,将会优先使用该类型的String方法返回结果,进行打印。
由此引出:
// json包
func Marshal(v interface{}) (data []byte, err error)
func Unmarshal(data []byte, v interface{}) error
// 序列化interface
type Marshaler interface {
MarshalJSON() ([]byte, error)
}
// 反序列化interface
type Unmarshaler interface {
UnmarshalJSON([]byte) error
}
在进行json序列化和反序列化时,如果数据类型自己定义了序列化和反序列化行为。则我们在json.Marshal(data)
和json.Unmarshal(data, v)
时,遇到这种数据数据,默认会使用自定义的序列化和反序列化。例如:
type SaleOrder struct {
CreatedAt CustomTime `json:"created_at"`
SaleOrderId int `json:"sale_order_id"`
}
type CustomTime time.Time
func (c *CustomTime) MarshalJSON() ([]byte, error) {
...
}
func (c *CustomeTime) UnmarshalJSON(data []byte, v interface{}) error{
...
}
// 则我们在反序列化[]byte时
so :=&SaleOrder{
CreatedAt: "2017-10-21",
SaleOrderId: 1234,
}
// 会调用CustomTime的序列化方法
if bts, err:= json.Marshal(so); err !=nil{
log.Fatal(err.Error())
return
}
// 会调用CustomTime的反序列化方法
if err = json.Unmarshal(bts, so); err !=nil{
log.Fatal(err.Error())
return
}
经验总结:我们以后遇到需要对数据进行处理的时候,如果当前的处理不支持,可以查看是否有处理的interface类型,有的话,就自定义实现。