2016-08-20 7 views
0

私は "RPUSH"コマンドで私の赤いベースのオブジェクトをプッシュしています。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())) 

Redigo私が期待していることは、ゴブエンコードされたすべてのデータ構造をプッシュしています。

今、私はそれらを盗んしようとしている:

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するためにそれらを最良の方法は何ですか?私はそれらをインタフェース{}のスライスとして戻したいと思っています。しかし、私のオブジェクトがゴブデータとしてエンコードされていても。彼らはredisの方法でプッシュされるので、それはゴブのポイントビューからスライスとして考えることができますか?

他のリストを反復して1つずつデコードすることができます。しかし、私は効率について自信がありません。私は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())) 

ネットワークを使用します。文字列の割り当てを避けるためのバイト()。 RPUSHから整数の戻り値をデコードするには、redis.Intを使用します。あなたは、リストから返された要素の数を気にしないかのようにそれを書き、

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

か::私は期待していたまさにでしたこと、

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

はありがとうようなコードを記述します。 –

関連する問題