2012-09-27 11 views
5

Estoy redigo para conectarse desde Ir a una base de datos redis. ¿Cómo puedo convertir un tipo de []interface {}{[]byte{} []byte{}} en un conjunto de cadenas? En este caso me gustaría obtener las dos cadenas Hello y World.redigo, SMEMBERS, cómo obtener cadenas

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? 
} 

Respuesta

4

Mirando el código fuente para el módulo, se puede ver el type signature returned from Receive habrá:

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

y en su caso, que está utilizando MultiBulk:

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

Esto da una respuesta de múltiples interface{} 's en una porción: []interface{}

antes de un interface{} sin tipear tienes que assert its type este modo:.

x (T)

Dónde T es un tipo (por ejemplo, int, string etc.)

En su caso, usted tiene una rebanada de interfaces (tipo: []interface{}) Por lo tanto, si quieres un string, es necesario afirmar en primer lugar que cada uno tiene el tipo bytes [], y luego las echó en una cadena de por ejemplo:

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

He aquí un ejemplo: http://play.golang.org/p/ZifbbZxEeJ

También puede utilizar un detector de comprobar qué tipo de datos que volvió:

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

O, como alguien ha mencionado, utilizar el construido en redis.String etc. métodos que los verificarán y convertirán para usted.

Creo que la clave es , cada una necesita ser convertida, no puedes simplemente hacerlas como un pedazo (a menos que escribas un método para hacerlo!).

8

Buscar en 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á en (v interface{}, err error)(string, error)

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

reemplazar con

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

Aparece el siguiente error: 'redigo: tipo inesperado para Cadena, tiene el tipo [] interfaz {}' de la línea anterior ... – topskip

+0

@topskip: Probablemente no sea necesario decir esto ya que esta pregunta ya tiene una respuesta, pero el error de tipo no ejecutado probablemente se debe a que está insertando un segmento de interfaces en lugar de solo la interfaz. Si hubieras enumerado a través de la porción de interfaces y utilizara redis.String, probablemente funcionaría bien. – bleakgadfly

2

Para hacer una publicidad de mi propio producto: simplemente eche un vistazo a http://cgl.tideland.biz. Allí también encontrarás mi cliente de Redis. Es compatible con cada comando, así como con comandos múltiples y pub/sub.Como valor de retorno, obtiene un conjunto de resultados que le permite un acceso conveniente a valores de retorno simples o múltiples o hashes junto con métodos para la conversión a los tipos de Go nativos.

Cuestiones relacionadas