2016-08-20 110 views
0

我正在使用「RPUSH」命令在我的redis基礎中推入我的對象。redigo和gob如何檢索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())) 

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 

什麼是採空區,DECOD他們的最好方法是什麼?我想把它們作爲一個界面切片{}。但即使我的對象被編碼爲gob數據。他們被推到redis的方式,所以它可以被認爲是從gob的角度來看的一個切片?

我可以迭代其他列表並逐個解碼它們。但我對效率沒有信心。我假設gob想要一個以它的方式編碼的片結構。所以我的問題是:爲了有效地解碼我的gob數據片作爲一個數據結構集合有沒有一個技巧?或者我應該以另一種方式存儲我的數據結構(我假設用RPUSH存儲我的數據可以防止非原子操縱)

回答

1

LRANGE命令返回一個列表。使用redis.ByteSlices將該列表作爲[] []字節獲取。解碼列表中的每個採空區:

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,然後採空區編碼整個列表並將其存儲爲體字符串:

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

使用網絡。 Bytes()避免字符串分配。使用redis.Int來解碼RPUSH的整數返回值。寫代碼:

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

,或者如果你不關心從列表中返回的元素的個數,寫爲:

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

謝謝,這正是我所期待的。 –