为从JSON读取的数据分配适当的类型

I have a struct such as this one:

type Data struct {
    Id         string
    Value      string
    Custom     customtype1
    Special    customtype2
    TimeStamp  Time        
}

var model Data

I am reading data from a JSON object. Because the JSON is structured very differently, I can't just directly unmarshall the JSON into the struct. So I am trying to "match" the fields from the JSON objects to those of the struct one by one. I don't actually need to properly unmarshall the JSON data into the struct, all I really need is to be able to assign, for each field, the proper type to its value.

So I unmarshall the JSON to a generic interface, then convert it to a map[string]interface{} and iterate over that. For each field, I try to find a match among the field names in the model variable which I get using reflect.

Now this all works fine, but the problem arises when I try to get the right type for the values.

I can get the Type for a certain field from the model using reflect, but then I can't use that to cast the type of the value I get from the JSON because that is not a type. I can't use a switch statement either, because this is a simplified version of the situation and in reality I'm dealing with 1000+ different possible types. How can I convert the values I have for each field into their proper type ?

The only I can think of solving this would be to recreate a json string that matches the format of the struct and then unmarshall that into its proper struct, but that seems way to convoluted. Surely there must be a simpler way?

Here's a sample JSON (I can not change this structure, unless I rework it within my Go program):

{
    "requestId": 101901,
    "userName": "test",
    "options": [1, 4],
    "request": {
        "timeStamp": {
            "Value1": "11/02/2018",
            "Value2": "11/03/2018"
        },
        "id": {
            "Value1": "123abcd",
            "Value2": "0987acd",
            "Value3": "a9c003"
        },
        "custom": {
            "Value1": "customtype1_value",
            "Value2": "customtype1_value"
        }
    }
}

I'd advise against your current approach. You haven't provided enough context to tell us why you're choosing to unmarshall things one by one, but Go's support for JSON is good enough that I'd guess it is capable of doing what you want.

Are you aware of Marshall's support for struct tags? Those might serve the purpose you're looking for. Your struct would then look something more like:

type Data struct {
    Id         string       `json:"id"`
    Value      string       `json:"value"`
    Custom     customtype1  `json:"custom_type"`
    Special    customtype2  `json:"special_type"`
    TimeStamp  Time         `json:"timestamp"`
}

If your problem is that the custom types don't know how to be unmarshalled, you can define custom unmarshalling functions for them.

This would then enable you to unmarshall an object like the following:

{
  "id": "foo",
  "value": "bar",
  "custom_type": "2342-5234-4b24-b23a",
  "special_type": "af23-af2f-rb32-ba23",
  "timestamp": "2018-05-01 12:03:41"
}