golang中的原生包endcoding/json提供了序列化和反序列化json数据的功能
我们可以使用encoding/json中的Encoder.Encode()和Marshal()实现json序列化;使用Decoder.Decode()和Unmarshal()实现json反序列化
type Metric struct {
Name string `json:"name"`
Value int64 `json:"value"`
}
func main() {
_ = json.NewEncoder(os.Stdout).Encode(
[]*Metric{
{"vv", 12},
{"tz", 9},
{"ss", 89},
},
)
}
输出结果为:
$ go run main.go
[{"name":"vv","value":12},{"name":"tz","value":9},{"name":"ss","value":89}]
Metricencoder
如果存在这样一种情况,我们需要接收另外一个进程传入的json数据,进行反序列化,我们都知道json反序列化到指定结构体时,需要遵循这个结构体对数据类型的定义
Metricstringint64
func main() {
var metric Metric
err := json.Unmarshal([]byte(`{"name":"tq","value":1.1}`), &metric)
if err != nil {
panic(err)
}
fmt.Println(metric)
}
panic(err)Metric
在encoding/json包中有两个非常重要的接口:
// Marshaler is the interface implemented by types that
// can marshal themselves into valid JSON.
type Marshaler interface {
MarshalJSON() ([]byte, error)
}
// Unmarshaler is the interface implemented by types
// that can unmarshal a JSON description of themselves.
// The input can be assumed to be a valid encoding of
// a JSON value. UnmarshalJSON must copy the JSON data
// if it wishes to retain the data after returning.
//
// By convention, to approximate the behavior of Unmarshal itself,
// Unmarshalers implement UnmarshalJSON([]byte("null")) as a no-op.
type Unmarshaler interface {
UnmarshalJSON([]byte) error
}
MarshalerUnmarshaler
MetricUnmarshaler
func (m *Metric) UnmarshalJSON(data []byte) error {
type AliasMetric Metric
t := &struct {
Value float64 `json:"value"`
*AliasMetric
}{
Value: float64(m.Value),
AliasMetric: (*AliasMetric)(m),
}
if err := json.Unmarshal(data, &t); err != nil {
return err
}
m.Value = int64(t.Value)
return nil
}
核心思想就是以结构体新类型,让新类型获得原始结构体的所有字段属性,但是却不会继承原有结构体的方法
Metric
func main() {
metric := &Metric{}
//err := json.Unmarshal([]byte(`{"name":"tq","value":1.1}`), &metric)
if err := metric.UnmarshalJSON([]byte(`{"name":"tq","value":1.1}`)); err != nil {
panic(err)
}
fmt.Println(*metric)
}
输出结果为:
$ go run main.go
{tq 1}