GoLang Redis: карта и фрагмент - PullRequest
0 голосов
/ 16 ноября 2018

Я использую GoLang для получения данных из хэша Redis и затем сопоставления со структурой.

type Person struct {
    ID         string       `json:"id"`
    FirstName  string       `json:"firstName"`
    LastName   string       `json:"lastName"`
    Filters    interface{}  `json:"filters"`
    Type       string       `json:"type"`
}

В Redis хеш-поле содержит строковый JSON.

HGET hashname fieldname

Выше возвращает строковый JSON.

Теперь ключом «filters» может быть массив или карта, основанная на типе (поэтому я определил тип Filters как интерфейс в struct).
Я собираю JSON, как показано ниже:

var p Person
content, err := redis.HGet("hashName", "id").Result()
_ = json.Unmarshal([]byte(content), &p)

Теперь я должен зацикливаться на фильтрах, как показано ниже, но это дает ошибку, что не может выходить за пределы p.Filters (типинтерфейс {}) (я понимаю, почему возникает эта ошибка)

for _, filter := range p.Filters {
  fmt.Println(filter)
}

Можно ли как-то справиться с этой ситуацией?

Спасибо,
Шашанк

1 Ответ

0 голосов
/ 16 ноября 2018

Вам нужно конвертировать Filters type interface{} в ожидаемый фрагмент. Если вы действительно не знаете, какой это будет тип, вы можете использовать map[string]interface{}. Поэтому измените тип Filters на map[string]interface{}.

За дополнительной информацией Если Filters может быть массивом (или нет), то вы можете рассмотреть type switch:

Простой пример:

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    var i interface{}
    //json.Unmarshal([]byte(`["hi"]`), &i)
    json.Unmarshal([]byte(`{"a":"hi"}`), &i)

    switch i.(type) {
    case []interface{}:
        println("ARRAY")
    case map[string]interface{}:
        println("NOT ARRAY")
    default:
        fmt.Printf("%T\n", i)
    }
}
...