Handling Replies
Redis commands return various data types, and the conn.Do()
method in Redigo returns these as interface{}
. To make working with these replies easier and safer, Redigo provides a suite of helper functions to convert the generic reply into a specific Go type.
All helper functions share a common signature: func(reply interface{}, err error) (T, error)
. If the input err
is not nil
, the helper immediately returns it. This allows for convenient chaining:
// The error from c.Do is passed directly into redis.String
s, err := redis.String(c.Do("GET", "mykey"))
if err != nil {
// This 'err' could be from the c.Do call or from the type conversion.
}
Nil Replies
When a Redis command returns a nil bulk string (e.g., GET
on a non-existent key), the helpers return the zero value for their type and the special error redis.ErrNil
.
s, err := redis.String(c.Do("GET", "nonexistent_key"))
if err == redis.ErrNil {
fmt.Println("Key does not exist.")
} else if err != nil {
// some other error
} else {
fmt.Println("Key exists:", s)
}
Basic Type Helpers
These helpers convert replies to common scalar Go types.
redis.String(reply, err)
: Converts a bulk or simple string reply tostring
.redis.Bytes(reply, err)
: Converts a bulk or simple string reply to[]byte
.redis.Int(reply, err)
: Converts an integer or bulk string reply toint
.redis.Int64(reply, err)
: Converts an integer or bulk string reply toint64
.redis.Uint64(reply, err)
: Converts an integer or bulk string reply touint64
.redis.Float64(reply, err)
: Converts a bulk string reply tofloat64
.redis.Bool(reply, err)
: Converts an integer reply tobool
(0
is false, others are true).
Array & Slice Helpers
These helpers are used for commands that return arrays, such as LRANGE
, SMEMBERS
, or MGET
.
redis.Values(reply, err)
: Converts an array reply to[]interface{}
. This is the most generic array helper.redis.Strings(reply, err)
: Converts an array of bulk strings to[]string
.redis.ByteSlices(reply, err)
: Converts an array of bulk strings to[][]byte
.redis.Ints(reply, err)
: Converts an array of integers/bulk strings to[]int
.
// Example using LRANGE
values, err := redis.Strings(c.Do("LRANGE", "mylist", 0, -1))
if err != nil {
// handle error
}
for _, v := range values {
fmt.Println(v)
}
Map Helpers
These helpers are perfect for commands like HGETALL
that return an array of alternating keys and values.
redis.StringMap(reply, err)
: Converts an array reply tomap[string]string
.redis.IntMap(reply, err)
: Converts tomap[string]int
.redis.Int64Map(reply, err)
: Converts tomap[string]int64
.
// Example using HGETALL
attributes, err := redis.StringMap(c.Do("HGETALL", "user:100"))
if err != nil {
// handle error
}
fmt.Println("Name:", attributes["name"])
Scanning Helpers
Redigo provides powerful scanning functions to map array replies directly into Go variables or structs.
Scan
Scan
copies elements from an array reply into the variables pointed to by dest
.
var val1 int
var val2 string
reply, err := redis.Values(c.Do("MGET", "key1", "key2"))
if err != nil {
// handle error
}
if _, err := redis.Scan(reply, &val1, &val2); err != nil {
// handle error
}
// val1 and val2 are now populated.
ScanStruct
ScanStruct
maps the alternating key-value pairs from a reply (like HGETALL
) into the fields of a struct. Field names are matched by default, but can be customized with a redis:"..."
tag.
type User struct {
Name string `redis:"name"`
Age int `redis:"age"`
}
var u User
reply, err := redis.Values(c.Do("HGETALL", "user:100"))
if err != nil {
// handle error
}
if err := redis.ScanStruct(reply, &u); err != nil {
// handle error
}
fmt.Printf("%+v\n", u) // {Name:John Doe Age:30}