通过更改JSON属性取消编组

I have a JSON object whose details can contain different types of JSON objects, the rest of the JSON remains the same, in such a case how can I have a single struct in Golang to handle both types of 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":""
   }
}

My goal is to use a single struct for both these JSON objects. In a language like Java I would create a Parent Class which resembles details in a generic way and have 2 child classes to resemble the type of details that vary and during runtime I would create an object of a child type and assign it to the Parent. I am unsure how this is done in Go.

I am not sure you can have a single struct unless you are ok with a string interface map, but You can prevent the details from being decoded by setting them as a json.RawMessage type int he struct. You can then decode the unknown-typed json data by attempting to decode it into one type, if that returns an error then you try with the next type.

Here is some code, that should give you a better idea to what I am talking about.

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
", d1)
    fmt.Printf("%+v
", 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
", b1)
    }
    err = json.Unmarshal([]byte(d1.Details), &b2)
    if err == nil {
        fmt.Printf("d1 is an detailstwo struct: %+v
", b2)
    }

    // json2
    err = json.Unmarshal([]byte(d2.Details), &b1)
    if err == nil {
        fmt.Printf("d2 is an []int: %+v
", b1)
    }
    err = json.Unmarshal([]byte(d2.Details), &b2)
    if err == nil {
        fmt.Printf("d2 is an detailstwo struct: %+v
", b2)
    }
}
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
}

you can find filled struct by comparing them with nil