我正在使用“RPUSH”命令将我的对象推入我的对象。
select
Redigo做我所期待的,它正在推动gob编码的所有数据结构。
现在我正在尝试撤回他们:
// 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()))
gob-decod它们的最佳方法是什么?我想把它们作为一个接口{}切片。但即使我的对象被编码为gob数据。它们是以redis的方式推动的,所以它可以被视为从gob的角度看的切片吗?
我可以迭代其他列表并逐个解码。但我对效率没有信心。我假设gob想要以其方式编码的切片结构。所以我的问题是:是否有一个技巧可以有效地解码我的切片数据作为数据结构的集合?或者我应该以另一种方式存储我的数据结构(我假设使用RPUSH存储我的数据可以防止非基本操作)
答案 0 :(得分:1)
LRANGE命令返回一个列表。使用redis.ByteSlices将该列表作为[] []字节。解码列表中的每个gob:
for rule in items.filtered("eqp_pricelist"):
这假定为推入列表的每个值创建了一个新的gob.Encoder。
如果应用程序没有在Redis中独立访问列表项,那么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)
}
以下是解码方法:
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
}
使用network.Bytes()来避免字符串分配。使用redis.Int解码RPUSH中的整数返回值。将代码写为:
redis.String(d.Conn.Do("RPUSH", "objects", network.String()))
或者如果您不关心从列表返回的元素数,请将其写为:
n, err := redis.Int(d.Conn.Do("RPUSH", "objects", network.Bytes()))