英文:
redigo, SMEMBERS, how to get strings
问题
如何将类型为[]interface {}{[]byte{} []byte{}}
的数据转换为一组字符串?在这种情况下,我想要得到两个字符串Hello
和World
。
英文:
I am redigo to connect from Go to a redis database. How can I convert a type of []interface {}{[]byte{} []byte{}}
to a set of strings? In this case I'd like to get the two strings Hello
and World
.
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?
}
答案1
得分: 8
在模块源代码中查找
// String是一个将Redis回复转换为字符串的辅助函数。
//
// 回复类型 结果
// 整数 格式为十进制字符串
// 块 作为字符串返回回复
// 字符串 原样返回
// 空 返回错误ErrNil
// 其他 返回错误
func String(v interface{}, err error) (string, error) {
redis.String
将在(v interface{}, err error)
中转换为(string, error)
reply, err := redis.MultiBulk(c.Receive())
替换为
s, err := redis.String(redis.MultiBulk(c.Receive()))
英文:
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()))
答案2
得分: 4
查看模块的源代码,你可以看到从Receive返回的类型签名将是:
func (c *conn) Receive() (reply interface{}, err error)
在你的情况下,你正在使用MultiBulk:
func MultiBulk(v interface{}, err error) ([]interface{}, error)
这将在一个切片中返回多个interface{}
类型的回复:[]interface{}
在未指定类型的interface{}
之前,你必须像这样断言其类型:
x.(T)
其中T
是一个类型(例如,int
,string
等)
在你的情况下,你有一个接口切片(类型为[]interface{}
),所以如果你想要一个string
,你需要首先断言每个元素的类型为[]byte
,然后将它们转换为string
,例如:
for _, x := range reply {
var v, ok = x.([]byte)
if ok {
fmt.Println(string(v))
}
}
这里有一个示例:http://play.golang.org/p/ZifbbZxEeJ
你还可以使用类型开关来检查返回的数据类型:
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是一个int
等等...
}
}
或者,正如有人提到的,使用内置的redis.String
等方法来检查和转换它们。
我认为关键是,每个元素都需要转换,你不能只是一次性转换它们(除非你编写一个方法来这样做!)。
英文:
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!).
答案3
得分: 1
由于redis.MultiBulk()
现在已经被弃用,使用redis.Values()
并将结果转换为String
可能是一个好的方法:
import "github.com/gomodule/redigo/redis"
type RedisClient struct {
Conn redis.Conn
}
func (r *RedisClient) SMEMBERS(key string) interface{} {
tmp, err := redis.Values(r.Conn.Do("smembers", key))
if err != nil {
fmt.Println(err)
return nil
}
res := make([]string, 0)
for _, v := range tmp {
res = append(res, string(v.([]byte)))
}
return res
}
英文:
Since redis.MultiBulk()
now is deprecated, it might be a good way to use redis.Values()
and convert the result into String
:
import "github.com/gomodule/redigo/redis"
type RedisClient struct {
Conn redis.Conn
}
func (r *RedisClient) SMEMBERS(key string) interface{} {
tmp, err := redis.Values(r.Conn.Do("smembers", key))
if err != nil {
fmt.Println(err)
return nil
}
res := make([]string, 0)
for _, v := range tmp {
res = append(res, string(v.([]byte)))
}
return res
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论