2012-09-27 14 views
5

Jestem redigo, aby połączyć się z Idź do bazy danych redis. Jak przekonwertować typ []interface {}{[]byte{} []byte{}} na zestaw ciągów znaków? W tym przypadku chciałbym uzyskać dwa ciągi znaków: Hello i World.redigo, SMEMBERS, czyli jak uzyskać ciągi znaków

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

Odpowiedz

4

Patrząc na kod źródłowy dla modułu, można zobaczyć type signature returned from Receive będą:

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

iw Twoim przypadku, używasz MultiBulk:

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

Daje to odpowiedź wielokrotnej interface{} w plasterku: []interface{}

Przed nieprzypisanym interface{} musisz assert its type tak:.

x (T)

Gdzie T to typ (np int, string itp)

W twoim przypadku, masz kawałek interfejsów (typ: []interface{}) tak więc, jeśli chcesz string, trzeba najpierw stwierdzić, że każdy z nich ma typ [] bajtów, a następnierzucać je na np strun:

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

Oto przykład: http://play.golang.org/p/ZifbbZxEeJ

Można również użyć przełącznika typu, by sprawdzić, jaki rodzaj danych, które dostał z powrotem:

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

Albo, jak ktoś wspomniał, korzystać z wbudowanych redis.String itp. metody, które sprawdzą i skonwertują je dla ciebie.

Myślę, że kluczem jest, każdy musi zostać przekonwertowany, nie można po prostu zrobić ich jako porcji (chyba że napiszesz metodę, aby to zrobić!).

8

Look w 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 przekonwertuje (v interface{}, err error) w (string, error)

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

zastąpić

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

Pojawia się następujący błąd: 'redigo: nieoczekiwany typ dla String, otrzymałem typ [] interface {}' z twojej linii powyżej ... – topskip

+0

@topskip: Prawdopodobnie nie trzeba tego mówić, ponieważ to pytanie już ma odpowiedź, ale nieoczekiwany błąd typu wynika prawdopodobnie z tego, że wstawiasz kawałek interfejsu zamiast samego interfejsu. Gdybyś wyliczył przez kawałek interfejsów i użył redis. Tring prawdopodobnie by działał dobrze. – bleakgadfly

2

Aby zrobić reklamę dla mojego produktu: wystarczy spojrzeć na http://cgl.tideland.biz. Znajdziesz tam również mojego klienta Redis. Obsługuje każde polecenie, a także wiele poleceń i pub/sub.Jako wartość zwracana otrzymujesz zestaw wyników, który umożliwia wygodny dostęp do pojedynczych lub wielu wartości zwracanych lub skrótów wraz z metodami konwersji do rodzimych typów Go.

Powiązane problemy