Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go:使用多种类型对JSON进行解组_Json_Go_Struct_Types_Unmarshalling - Fatal编程技术网

Go:使用多种类型对JSON进行解组

Go:使用多种类型对JSON进行解组,json,go,struct,types,unmarshalling,Json,Go,Struct,Types,Unmarshalling,我在将JSON响应解包到结构中时遇到了一个问题。我遇到的问题是,邮政编码可以作为字符串或整数返回。如何编写一个unmarshal方法来检查zip是否为int并强制它将其存储为字符串 结构: type CustomerAddress struct { Line1 string `json:"line1"` City string `json:"city"` State string `json:"state

我在将JSON响应解包到结构中时遇到了一个问题。我遇到的问题是,邮政编码可以作为字符串或整数返回。如何编写一个unmarshal方法来检查zip是否为int并强制它将其存储为字符串

结构:

type CustomerAddress struct {
    Line1            string `json:"line1"`
    City             string `json:"city"`
    State            string `json:"state"`
    Zip              string `json:"zip"`
    IsPrimaryAddress string `json:"isPrimaryAddress"`
}
Json示例:

address": [
  {
    "line1": "555 ADDRESS PLACE",
    "city": "DALLAS",
    "state": "TX",
    "isPrimaryAddress": "Y",
    "zip": 55555
  }
]
解组后,结果应将zip成功转换为字符串:

address": [
  {
    "line1": "555 ADDRESS PLACE",
    "city": "DALLAS",
    "state": "TX",
    "isPrimaryAddress": "Y",
    "zip": "55555"
  }
]
作为一种尝试,我试着使用拉链

type CustomerAddress struct {
    Line1            string        `json:"line1"`
    City             string        `json:"city"`
    State            string        `json:"state"`
    Zip              ZipWrapper    `json:"zip"`
    IsPrimaryAddress string        `json:"isPrimaryAddress"`
}

type ZipWrapper struct {
   Zip string
}

func (w *ZipWrapper ) UnmarshalJSON(data []byte) (err error) {

    if zip, err := strconv.Atoi(string(data)); err == nil {
        w.Zip = strconv.Itoa(zip)
        return nil
    }
    return json.Unmarshal(data, &w.Zip)
}
这几乎奏效了,除了zip现在是CustomerAddress中的嵌套结构,这不是我想要的:

  address": [
  {
    "line1": "555 ADDRESS PLACE",
    "city": "DALLAS",
    "state": "TX",
    "isPrimaryAddress": "Y",
    "zip": {
      "Zip": "55555"
    }
  }
]

有什么想法吗?我觉得这是一项相对简单的任务,但我是一个十足的傻瓜,还没有完全了解解组的工作原理。

json包提供了执行此操作的类型:

type CustomerAddress struct {
    Line1            string      `json:"line1"`
    City             string      `json:"city"`
    State            string      `json:"state"`
    Zip              json.Number `json:"zip"`
    IsPrimaryAddress string      `json:"isPrimaryAddress"`
}

如果需要自己在没有嵌套结构的情况下执行此操作,则可以使用与
json.Number
相同的方式声明类型,并将
string
作为基础类型

type ZipWrapper string

func (w *ZipWrapper) UnmarshalJSON(data []byte) (err error) {
    if len(data) > 1 && data[0] == '"' && data[len(data)-1] == '"' {
        data = data[1 : len(data)-1]
    }

    if _, err := strconv.Atoi(string(data)); err != nil {
        return err
    }
    *w = ZipWrapper(string(data))
    return nil
}

json
包提供了执行此操作的类型:

type CustomerAddress struct {
    Line1            string      `json:"line1"`
    City             string      `json:"city"`
    State            string      `json:"state"`
    Zip              json.Number `json:"zip"`
    IsPrimaryAddress string      `json:"isPrimaryAddress"`
}

如果需要自己在没有嵌套结构的情况下执行此操作,则可以使用与
json.Number
相同的方式声明类型,并将
string
作为基础类型

type ZipWrapper string

func (w *ZipWrapper) UnmarshalJSON(data []byte) (err error) {
    if len(data) > 1 && data[0] == '"' && data[len(data)-1] == '"' {
        data = data[1 : len(data)-1]
    }

    if _, err := strconv.Atoi(string(data)); err != nil {
        return err
    }
    *w = ZipWrapper(string(data))
    return nil
}

Jim在另一个关于将ZipWrapper定义为字符串的回答中说的是,您可以采用与以前相同的方法,但不使用嵌套结构

像这样定义字段:

Zip ZipWrapper `json:"zip"`
func (w *ZipWrapper) UnmarshalJSON(data []byte) (err error) {

    if zip, err := strconv.Atoi(string(data)); err == nil {
        str := strconv.Itoa(zip)
        *w = ZipWrapper(str)
        return nil
    }
    var str string
    err = json.Unmarshal(data, &str)
    if err != nil {
       return err
    }
    return json.Unmarshal([]byte(str), w)
}
但是
ZipWrapper
的定义如下:

type ZipWrapper string
您的
UnmarshalJSON
函数可以如下所示:

Zip ZipWrapper `json:"zip"`
func (w *ZipWrapper) UnmarshalJSON(data []byte) (err error) {

    if zip, err := strconv.Atoi(string(data)); err == nil {
        str := strconv.Itoa(zip)
        *w = ZipWrapper(str)
        return nil
    }
    var str string
    err = json.Unmarshal(data, &str)
    if err != nil {
       return err
    }
    return json.Unmarshal([]byte(str), w)
}
这是一个工作场地:


Jim在另一个关于将ZipWrapper定义为字符串的回答中说,您可以采用与以前相同的方法,但不使用嵌套结构

像这样定义字段:

Zip ZipWrapper `json:"zip"`
func (w *ZipWrapper) UnmarshalJSON(data []byte) (err error) {

    if zip, err := strconv.Atoi(string(data)); err == nil {
        str := strconv.Itoa(zip)
        *w = ZipWrapper(str)
        return nil
    }
    var str string
    err = json.Unmarshal(data, &str)
    if err != nil {
       return err
    }
    return json.Unmarshal([]byte(str), w)
}
但是
ZipWrapper
的定义如下:

type ZipWrapper string
您的
UnmarshalJSON
函数可以如下所示:

Zip ZipWrapper `json:"zip"`
func (w *ZipWrapper) UnmarshalJSON(data []byte) (err error) {

    if zip, err := strconv.Atoi(string(data)); err == nil {
        str := strconv.Itoa(zip)
        *w = ZipWrapper(str)
        return nil
    }
    var str string
    err = json.Unmarshal(data, &str)
    if err != nil {
       return err
    }
    return json.Unmarshal([]byte(str), w)
}
这是一个工作场地:


刚刚尝试使用json.Number,zip在最终结构中以数字而不是字符串的形式返回。它绝对必须是字符串,因为使用它的客户端应用程序希望它是字符串。你能解释一下如何将ZipWrapper类型定义为字符串吗?谢谢你的快速回复@xPeaWhyTee:你所说的“拉链作为一个数字返回”是什么意思
json.Number
是一个字符串,但它有将其转换为int64或float64的方法。当使用json.Number作为字段类型时,zip返回为:{“zip”:5555555},而不是{“zip”:“55555”}。但我意识到我读你答案的第二部分太快了,误解了你的意思。您的解组功能工作得非常好。谢谢刚刚尝试使用json.Number,zip在最终结构中以数字而不是字符串的形式返回。它绝对必须是字符串,因为使用它的客户端应用程序希望它是字符串。你能解释一下如何将ZipWrapper类型定义为字符串吗?谢谢你的快速回复@xPeaWhyTee:你所说的“拉链作为一个数字返回”是什么意思
json.Number
是一个字符串,但它有将其转换为int64或float64的方法。当使用json.Number作为字段类型时,zip返回为:{“zip”:5555555},而不是{“zip”:“55555”}。但我意识到我读你答案的第二部分太快了,误解了你的意思。您的解组功能工作得非常好。谢谢谢谢你的澄清。事实上,我在重读了他的答案后意识到了这一点。谢谢你的澄清。事实上,我在重读了他的答案后意识到了这一点。