为非内置类型定义自定义解组 [英] Defining custom unmarshalling for non-built in types

查看:59
本文介绍了为非内置类型定义自定义解组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Most of us know that a JSON object can be unmarshaled with JSON tags:

var jsonData = `{"name": "Brown Bear"}`

type Elephant struct {
    Name string `json:"name"`
}

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

This is because string is a built in types. But what if Name were not a built in type, and we wanted to use this type across different structs?

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 解组器知道如何解组它?

Is there a way we can define the Name type so that the json unmarshaller knows how to unmarshal it?

PS:我要避免的解决方案是为 Elephant Feline Bear 创建 UnmarshalJSON 方法以上.最好只为 Name 类型创建一个方法.

PS: The solution I want to avoid is creating UnmarshalJSON methods for Elephant, Feline, and Bear above. It would be better to create a method just for the Name type.

推荐答案

请参见 <代码> json.Marshaler json.Unmarshaler encoding/json 包中的code> 类型,可让您为任意类型定义自定义JSON en/decoding函数.

See the json.Marshaler and json.Unmarshaler types in the encoding/json package which allow you to define custom JSON en/decoding functions for arbitrary types.

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("%#v\n", alice)
}
// main.Elephant{Name:main.Name{CommonName:"Alice", ScientificName:""}, Age:2}

这篇关于为非内置类型定义自定义解组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆