首页 > 解决方案 > GoLang Redis:地图和切片

问题描述

我正在使用 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 哈希名称字段名

上面返回一个字符串化的 JSON。

现在“filters”键可以是基于类型的数组或映射(这就是我将过滤器类型定义为结构中的接口的原因)。
我将 JSON 编组如下:

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

现在我必须遍历下面的过滤器,但这会给出不能超过 p.Filters (type interface {})的错误(我明白为什么会出现这个错误)

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

我们有什么办法可以处理这种情况吗?

谢谢,
沙尚克

标签: jsongoredis

解决方案


您需要将Filters类型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)
    }
}

推荐阅读