Unmarshal с изменением атрибута JSON - PullRequest
0 голосов
/ 24 июня 2018

У меня есть объект JSON, детали которого могут содержать различные типы объектов JSON, остальная часть JSON остается неизменной, в таком случае, как я могу иметь одну структуру в Golang для обработки обоих типов JSON

JSON 1:

{
   "field1":"",
   "field2":"",
   "field3":"",
   "field4":"",
   "field5":"",
   "field6":"",
   "field7":"",
   "details":{
      "detail1":"",
      "detail2":[
         {
            "arr1":"",
            "arr2":{
               "id":"",
               "name":""
            },
            "list":[
               {
                  "id":"",
                  "version":1,
                  "name":""
               }
            ]
         }
      ]
   },
   "user":{
      "id":"",
      "name":""
   }
}

JSON 2:

{
   "field1":"",
   "field2":"",
   "field3":"",
   "field4":"",
   "field5":"",
   "field6":"",
   "field7":"",
   "details":{
      "anotherdetail1":"",
      "anotherdetail2":[
         {
            "arr7":"",
            "arr8":{
               "id":"",
               "name":""
            },
            "arr10":{

            }
         }
      ]
   },
   "user":{
      "id":"",
      "name":""
   }
}

Моя цель - использовать одну структуру для обоих этих JSONобъекты.В таком языке, как Java, я создал бы Родительский класс, который напоминает детали в общем виде и имел бы 2 дочерних класса, чтобы напоминать тип деталей, которые меняются, и во время выполнения я бы создал объект дочернего типа и назначил его Родителю.Я не уверен, как это делается в Go.

Ответы [ 2 ]

0 голосов
/ 24 июня 2018
type Base struct {
    Data map[string]interface{}

    Details struct {
        *D1
        *D2
    } `json:"details"
}

type D1 struct {
    Detail1 string
    Detail2 string
}

type D2 struct {
    AnotherDetail1 string
    AnotherDetail2 string
}

Вы можете найти заполненную структуру, сравнив их с nil

0 голосов
/ 24 июня 2018

Я не уверен, что у вас может быть одна структура, если вы не в порядке с картой интерфейса строки, но Вы можете предотвратить декодирование details , установив их как json.RawMessage тип в структуре , Затем вы можете декодировать данные json неизвестного типа, пытаясь декодировать их в один тип, если это возвращает ошибку, тогда вы пытаетесь использовать следующий тип.

Вот код, который должен дать вам лучшее представление о том, о чем я говорю.

https://play.golang.org/p/06owmiJXNaO

package main

import (
    "encoding/json"
    "fmt"
)

const json1 = `{"name": "foo", "details":[1, 2, 3]}`
const json2 = `{"name": "foo", "details":{"a": [1, 2, 3]}}`

type data struct {
    Name    string          `json:"name"`
    Details json.RawMessage `json:"details"`
}

type detailsone []int

type detailstwo struct {
    A []int `json:"a"`
}

func main() {
    var d1, d2 data
    json.Unmarshal([]byte(json1), &d1)
    json.Unmarshal([]byte(json2), &d2)

    fmt.Printf("%+v\n", d1)
    fmt.Printf("%+v\n", d2)

    var err error
    var b1 detailsone
    var b2 detailstwo

    // json1
    err = json.Unmarshal([]byte(d1.Details), &b1)
    if err == nil {
        fmt.Printf("d1 is an []int: %+v\n", b1)
    }
    err = json.Unmarshal([]byte(d1.Details), &b2)
    if err == nil {
        fmt.Printf("d1 is an detailstwo struct: %+v\n", b2)
    }

    // json2
    err = json.Unmarshal([]byte(d2.Details), &b1)
    if err == nil {
        fmt.Printf("d2 is an []int: %+v\n", b1)
    }
    err = json.Unmarshal([]byte(d2.Details), &b2)
    if err == nil {
        fmt.Printf("d2 is an detailstwo struct: %+v\n", b2)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...