redigo, SMEMBERS, how to get strings

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 will convert (v interface{}, err error) in (string, error)

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

replace with

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

Looking at the source code for the module, you can see the type signature returned from Receive will be:

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

and in your case, you're using MultiBulk:

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

This gives a reply of multiple interface{} 's in a slice: []interface{}

Before an untyped interface{} you have to assert its type like so:

x.(T)

Where T is a type (eg, int, string etc.)

In your case, you have a slice of interfaces (type: []interface{}) so, if you want a string, you need to first assert that each one has type []bytes, and then cast them to a string eg:

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

Here's an example: http://play.golang.org/p/ZifbbZxEeJ

You can also use a type switch to check what kind of data you got back:

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

for _, y := range reply {
    switch i := y.(type) {
    case nil:
        printString("x is nil")
    case int:
        printInt(i)  // i is an int
    etc...
    }
}

Or, as someone mentioned, use the built in redis.String etc. methods which will check and convert them for you.

I think the key is, each one needs to be converted, you can't just do them as a chunk (unless you write a method to do so!).

Tags:

Go

Redis