1

我正在使用“RPUSH”命令推入我的 redis 基础对象。

// object is of type interface

var network bytes.Buffer
gob.NewEncoder(&network)
enc.Encode(object /* interface{} */)

redis.String(d.Conn.Do("RPUSH", "objects", network.String()))

Redigo 做我所期待的,它正在推动所有数据结构 gob 编码。

现在我正在尝试检索它们:

sall, _ := redis.Strings(d.Conn.Do("LRANGE", "todos", "0", "-1"))
fmt.Printf("%T", sall) // type []string as expected

// At this point, I have no idea if I should store the data in a buffer, or convert it directly as bytes. actually, here I'm lost
var network bytes.Buffer
var object []interface{}


dec := gob.NewDecoder(network)
err := dec.Decode(inout)
fmt.Printf("%v", err) // decode error:EOF

对它们进行解码的最佳方法是什么?我想将它们作为接口的一部分返回{}。但即使我的对象被编码为 gob 数据。都是用redis的方式推送的,那么从gob的角度看能不能算是一个切片呢?

我可以迭代其他列表并一一解码。但我对效率没有信心。我假设 gob 想要一个以它的方式编码的切片结构。所以我的问题是:有没有什么技巧可以有效地将我的 gob 数据片段解码为数据结构的集合?或者我应该以另一种方式存储我的数据结构(我假设用 RPUSH 存储我的数据可以防止非原子操作)

4

1 回答 1

3

LRANGE命令返回一个列表。使用redis.ByteSlices将该列表作为 [][] 字节获取。解码列表中的每个 gob:

items, err := redis.ByteSlices(d.Conn.Do("LRANGE", "objects", "0", "-1"))
if err != nil {
   // handle error
}
var values []*Object
for _, item := range items {
    var v Object
    if err := gob.NewDecoder(bytes.NewReader(item)).Decode(&v); err != nil {
        // handle error
    }
    values = append(values, &v)
}

这假设为推入列表的每个值创建了一个新的 gob.Encoder。

如果应用程序没有在 Redis 中独立访问列表项,则 gob 对整个列表进行编码并将其存储为批量字符串:

 var values []*Object
 var buf bytes.Buffer
 if err := gob.NewEncoder(&buf).Encode(values); err != nil {
     // handle error
 }
 if _, err := d.Conn.Do("SET", "objects", buf.Bytes()); err != nil {
     // handler error
 }

以下是如何解码它:

items, err := redis.Bytes(d.Conn.Do("GET", "objects"))
if err != nil {
    // handle error
}
var values []*Objects
if err := gob.NewDecoder(items).Decode(&values); err != nil {
    // handle error
}

这是问题中这行代码的一个旁白:

 redis.String(d.Conn.Do("RPUSH", "objects", network.String()))

使用 network.Bytes() 来避免字符串分配。使用 redis.Int 解码来自 RPUSH 的整数返回值。将代码编写为:

 n, err := redis.Int(d.Conn.Do("RPUSH", "objects", network.Bytes()))

或者如果您不关心从列表返回的元素数量,请将其写为:

 _, err := d.Conn.Do("RPUSH", "objects", network.Bytes())
于 2016-08-20T13:21:47.783 回答