2012-09-27 14 views
5

I am redigo per connettersi da Vai a un database redis. Come posso convertire un tipo di []interface {}{[]byte{} []byte{}} in un insieme di stringhe? In questo caso mi piacerebbe ottenere le due stringhe Hello e World.redigo, SMEMBERS, come ottenere stringhe

package main 

import (
    "fmt" 
    "github.com/garyburd/redigo/redis" 
) 

func main() { 
    c, err := redis.Dial("tcp", ":6379") 
    defer c.Close() 
    if err != nil { 
     fmt.Println(err) 
    } 
    c.Send("SADD", "myset", "Hello") 
    c.Send("SADD", "myset", "World") 
    c.Flush() 
    c.Receive() 
    c.Receive() 

    err = c.Send("SMEMBERS", "myset") 
    if err != nil { 
     fmt.Println(err) 
    } 
    c.Flush() 
    // both give the same return value!?!? 
    // reply, err := c.Receive() 
    reply, err := redis.MultiBulk(c.Receive()) 
    if err != nil { 
     fmt.Println(err) 
    } 
    fmt.Printf("%#v\n", reply) 
    // $ go run main.go 
    // []interface {}{[]byte{0x57, 0x6f, 0x72, 0x6c, 0x64}, []byte{0x48, 0x65, 0x6c, 0x6c, 0x6f}} 
    // How do I get 'Hello' and 'World' from this data? 
} 

risposta

4

Guardando il codice sorgente per il modulo, si può vedere il type signature returned from Receive saranno:

func (c *conn) Receive() (reply interface{}, err error)

e nel tuo caso, si sta utilizzando MultiBulk:

func MultiBulk(v interface{}, err error) ([]interface{}, error)

Questo dà un risposta di più interface{} in una sezione: []interface{}

Prima di un non specificato interface{} devi assert its type in questo modo:.

x (T)

Dove T è un tipo (ad esempio, int, string ecc)

Nel tuo caso, si dispone di una fetta di interfacce (tipo: []interface{}) quindi, se volete un string, è necessario affermare la prima che ognuno ha di tipo [] byte, e poi le precipitava un esempio stringa:

for _, x := range reply { 
    var v, ok = x.([]byte) 
    if ok { 
     fmt.Println(string(v)) 
    } 
} 

Ecco un esempio: http://play.golang.org/p/ZifbbZxEeJ

È possibile anche utilizzare un interruttore di tipo per verificare il tipo di dati sei tornato:

http://golang.org/ref/spec#Type_switches

Oppure, come qualcuno ha detto, utilizzare il costruito nel redis.String ecc. metodi che controllano e convertono per te.

Penso che la chiave sia, ognuno deve essere convertito, non si può semplicemente farli come un chunk (a meno che non si scriva un metodo per farlo!).

8

Look in module source code

// String is a helper that converts a Redis reply to a string. 
// 
// Reply type  Result 
// integer   format as decimal string 
// bulk   return reply as string 
// string   return as is 
// nil    return error ErrNil 
// other   return error 
func String(v interface{}, err error) (string, error) { 

redis.String convertirà (v interface{}, err error) in (string, error)

reply, err := redis.MultiBulk(c.Receive()) 

sostituirli con

s, err := redis.String(redis.MultiBulk(c.Receive())) 
+1

Viene visualizzato il seguente errore: 'redigo: tipo imprevisto per String, ottenuto tipo [] interface {}' dalla riga sopra ... – topskip

+0

@topskip: Probabilmente non è necessario dirlo poiché questa domanda ha già una risposta, ma l'errore di tipo non esaminato è probabilmente dovuto al fatto che stai inserendo una porzione di interfacce anziché solo l'interfaccia. Se si fosse enumerato attraverso la slice of interface e utilizzato redis.String, probabilmente funzionerebbe correttamente. – bleakgadfly

2

Per fare pubblicità per il mio prodotto: basta dare un'occhiata a http://cgl.tideland.biz. Lì troverai anche il mio client Redis. Supporta ogni comando così come multi-comandi e pub/sub.Come valore di ritorno si ottiene un set di risultati che consente un comodo accesso a valori di ritorno singoli o multipli o hash insieme ai metodi per la conversione nei tipi Go nativi.

Problemi correlati