redigo 和 gob 如何检索 gob 数据切片

redigo and gob how to retrieve slices of gob data

我正在使用 "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 解码的最佳方法是什么?我想将它们作为接口 {} 的一部分取回。但即使我的对象被编码为 gob 数据。都是redis方式推送的,那么从gob的角度看能不能算作一个slice?

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

LRANGE command returns a list. Use 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 解码整数 return 值。将代码写成:

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

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

 _, err := d.Conn.Do("RPUSH", "objects", network.Bytes())