为非内置类型定义自定义解组



我们大多数人都知道JSON对象可以使用JSON标签进行解组:

var jsonData = `{"name": "Brown Bear"}`
type Elephant struct {
    Name string `json:"name"`
}

这是因为string是内置类型。但是,如果Name不是内置类型,并且我们想在不同的结构中使用此类型呢?

var jsonData = `{"name": "Brown Bear"}`
type Elephant struct {
    Name Name   `json:"name"`  // Unmarshalling fails here
}
type Feline struct {
    Name Name   `json:"name"`  // Unmarshalling fails here
}
type Bear struct {
    Name Name   `json:"name"`  // Unmarshalling fails here
}
type Name struct {
    CommonName     string
    ScientificName string  // This field should intentionally be blank
}

有没有办法定义Name类型,以便json解组器知道如何解组它?

PS:我想避免的解决方案是为上面的ElephantFelineBear创建UnmarshalJSON方法。最好只为Name类型创建一个方法。

查看encoding/json包中的json.Marshalerjson.Unmarshaler类型,它们允许您为任意类型定义自定义JSON en/解码函数。

package main
import (
  "encoding/json"
  "fmt"
)
type Name struct {
  CommonName     string
  ScientificName string
}
func (n *Name) UnmarshalJSON(bytes []byte) error {
  var name string
  err := json.Unmarshal(bytes, &name)
  if err != nil {
    return err
  }
  n.CommonName = name
  n.ScientificName = ""
  return nil
}
type Elephant struct {
  Name Name `json:"name"`
  Age  int  `json:"age"`
}
func main() {
  alice := Elephant{}
  aliceJson := `{"name":"Alice","age":2}`
  err := json.Unmarshal([]byte(aliceJson), &alice)
  if err != nil {
    panic(err)
  }
  fmt.Printf("%#vn", alice)
}
// main.Elephant{Name:main.Name{CommonName:"Alice", ScientificName:""}, Age:2}

最新更新