go - redigo 和 gob 如何检索 gob 数据 slice

标签 go encoding gob redigo

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

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

最佳答案

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())

关于go - redigo 和 gob 如何检索 gob 数据 slice ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39052200/

相关文章:

php - 如何在 PHP 中使用带有 json_encode() 的瑞典字母?

go - 使用 gob 解码 rpc 回复时出现错误

gob 没有按预期解码

pointers - Golang,通过指针更改数组

php - 使用 PHP 向 Hotmail 发送电子邮件时的编码问题

go - 实例化结构和数组不会创建新的引用

c# - Encoding.RegisterProvider(CodePagesEncodingProvider.Instance) 不添加额外的编码提供者

sockets - 在 Go 中写入客户端 UDP 套接字

go - 处理动态子域

google-app-engine - google app engine datastore Go Query with "in"operator