Самостоятельно выполнить unmarshal метод или по умолчанию unmarshal method base при условии в golang - PullRequest
0 голосов
/ 23 октября 2018

Я новичок в Голанге.У меня есть структура Item .

type Item Struct{
   ...
}

, и я знаю, что у нее есть метод по умолчанию UnmarshalJSON .
Теперь я хочу разархивировать данные для него.

Для данных могут использоваться два разных формата.Итак, мое ожидание, как показано ниже:

if condition {
    //execute default UnmarshalJSON
    json.Unmarshal(data, &item) 
}else{
    //execute my own UnmarshalJSON
    json.Unmarshal(data, &item) 
}

, это мой собственный UnmarshalJSON.

func (item *Item) UnmarshalJSON(data []byte) error{
   ...
}

Возможно, сам UnmarshalJSON переопределит default, поэтому два метода не могут присутствовать одновременно.Я хочу знать, как решить такую ​​проблему, которая разбивает два разных формата данных в одну структуру.

1 Ответ

0 голосов
/ 23 октября 2018

Используйте интерфейс независимо от формата, который вы получаете от ответа json, и разархивируйте ответ в интерфейс следующим образом:

func main(){
    var result interface{}
    if err := json.Unmarshal(jsonbytes, &result); err != nil{
         fmt.Println(err)
    }
}

Затем используйте утверждение типа, чтобы извлечь значение, лежащее в основе интерфейса.Но я думаю, что в вашем случае, если вы не основной тип ключа.Лучше использовать рекурсию для получения значения.

func fetchValue(value interface{}) {
    switch value.(type) {
    case string:
        fmt.Printf("%v is an interface \n ", value)
    case bool:
        fmt.Printf("%v is bool \n ", value)
    case float64:
        fmt.Printf("%v is float64 \n ", value)
    case []interface{}:
        fmt.Printf("%v is a slice of interface \n ", value)
        for _, v := range value.([]interface{}) { // use type assertion to loop over []interface{}
            fetchValue(v)
        }
    case map[string]interface{}:
        fmt.Printf("%v is a map \n ", value)
        for _, v := range value.(map[string]interface{}) { // use type assertion to loop over map[string]interface{}
            fetchValue(v)
        }
    default:
        fmt.Printf("%v is unknown \n ", value)
    }
}

Рабочий код на Перейти на игровую площадку

Приведенный выше код позволит вам получить любой тип значения, которое анализируетсяв интерфейс.

Примечание:

В golang определено, что когда вы демаршируете неизвестный json в интерфейс.Он будет преобразован в следующие типы:

bool, for JSON booleans
float64, for JSON numbers
string, for JSON strings
[]interface{}, for JSON arrays // slice of interface{}
map[string]interface{}, for JSON objects
nil for JSON null
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...