在實際開發中,經常會遇到需要定制json編解碼的情況。
比如,按照指定的格式輸出json字符串,
又比如,根據條件決定是否在最后的json字符串中顯示或者不顯示某些字段。
如果希望自己定義對象的編碼和解碼方式,需要實現以下兩個接口:
type Marshaler interface {
MarshalJSON() ([]byte, error)
}
type Unmarshaler interface {
UnmarshalJSON([]byte) error
}
對象實現接口后,編解碼時自動調用自定義的方法進行編解碼。
下面例子中,自定義編解碼方法。
編碼時,將map轉化為字符串數組。
解碼時,將字符串數組轉化為map。
package main
import (
"encoding/json"
"fmt"
)
type Bird struct {
A map[string]string `json:"a"`
}
func (bd *Bird) MarshalJSON() ([]byte, error) {
l := []string{}
for _,v := range bd.A {
l = append(l,v)
}
return json.Marshal(l)
}
func (bd *Bird) UnmarshalJSON(b []byte) error {
l := []string{}
err := json.Unmarshal(b, &l)
if err != nil {
return err
}
for i,v := range l {
k := fmt.Sprintf("%d", i)
bd.A[k] = v
}
return nil
}
func main() {
m := map[string]string{"1": "110", "2":"120", "3":"119"}
xiQue := &Bird{A:m}
xJson, err := json.Marshal(xiQue)
if err != nil {
fmt.Println("json.Marshal failed:", err)
}
fmt.Println("xJson:", string(xJson))
b := `["apple", "orange", "banana"]`
baoXiNiao := &Bird{A:map[string]string{}}
err = json.Unmarshal([]byte(b), baoXiNiao)
if err != nil {
fmt.Println("json.Unmarshal failed:", err)
}
fmt.Println("baoXiNiao:", baoXiNiao)
}
output:
xJson: ["110","120","119"]
baoXiNiao: &{map[0:apple 1:orange 2:banana]}
