当前位置: 首页 > 工具软件 > Redigo > 使用案例 >

Golang redis(四)redigo类型转换及args传参详解

米景辉
2023-12-01

​ 因为go是强类型的一门语言,因此,因此经常需要将Golang与redis的数据类型进行对其,这就涉及到类型转换

数据类型之间的转换规则

Do发送args参数,需要对go原始的数据类型进行转换, 转换的规则如下:

GO数据类型               转换为/转换的方法:
[]byte                           []byte 
string                           string
int, int64                       strconv.FormatInt(v)
float64                          strconv.FormatFloat(v, 'g', -1, 64)
bool                             true -> "1", false -> "0"
nil                                  ""
其他类型                          fmt.Fprint(w, v)

redis 返回reply 与go的转换规则:

Redis返回类型                         Go数据类型
error                                redis.Error
integer                              int64
简单string                           string
大量string                            []byte 或 nil (如果值不存在).
array                                 []interface{} 或 nil (如果值不存在).

可以使用类型断言,或者reply 提供的帮助函数将interface{]转换为对应类型数据

类型转换

redigo提供了对应的类型转换函数,以方便进行类型转换

例如:

exists, err := redis.Bool(c.Do("EXISTS", "foo"))
if err != nil {
    // handle error return from c.Do or type conversion error.
}

Scan函数将数组回复的元素转换为Go类型, 在批量执行的时候,获取结果时,很有用处

var value1 int
var value2 string
reply, err := redis.Values(c.Do("MGET", "key1", "key2"))
if err != nil {
    // handle error
}
 if _, err := redis.Scan(reply, &value1, &value2); err != nil {
    // handle error
}

redigo函数

redigo提供了许多函数,帮助用户将回复命令进行数据转换,或者参数设置等

1 func Bool(reply interface{}, err error) (bool, error)

​ 转换为布尔值。如果err不等于nil,则Bool返回false,错误。否则Bool将回复转换为boolean

2 func ByteSlices(reply interface{}, err error) ([][]byte, error)

​ ByteSlices将数组命令的回复转换为[][]byte 二维数组。如果err不等于nil,则ByteSlices返回nil,错误。零数组项目保持无效。如果数组项不是批量字符串或nil,则ByteSlices返回错误

3 func Bytes(reply interface{}, err error) ([]byte, error)

​ 转换为[]bytes 一维数组

4 func DoWithTimeout(c Conn, timeout time.Duration, cmd string, args ...interface{}) (interface{}, error)

​ 执行命令, 拥有超时时间, 与Do用法基本一致,需要将connection 连接传入

5 func Float64(reply interface{}, err error) (float64, error)

​ 转换为float64, 如果err不等于nil,则Float64返回0,错误。否则,Float64将回复转换为int

规则如下

回复类型    	转换类型
bulk string   parsed reply, nil
nil           0, ErrNil
other         0, error

6 func Float64s(reply interface{}, err error) ([]float64, error)

​ 转换为[] float64, 如果err不等于nil,则Float64s返回nil,错误。Nil数组项在输出切片中转换为0。如果数组项不是批量字符串或nil,则Floats64返回错误

7 func Int(reply interface{}, err error) (int, error)

​ 转换为int

8 func Int64(reply interface{}, err error) (int64, error)

​ 转换为int64

​ 转换规则:

Reply type    Result
integer       reply, nil
bulk string   parsed reply, nil
nil           0, ErrNil
other         0, error

9 func Int64Map(result interface{}, err error) (map[string]int64, error)

​ 转换为map [string] int64

10 func Int64s(reply interface{}, err error) ([]int64, error)

​ 转换为[] int64 切片

11 func IntMap(result interface{}, err error) (map[string]int, error)

​ 转换为map [string] int

12 func Ints(reply interface{}, err error) ([]int, error)

​ 转换为[]int切片

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

​ 转换为[]interface{}

14 func Positions(result interface{}, err error) ([]*[2]float64, error)

​ 位置转换 将位置数组(lat,long)转换为[] [2] float64

15 func ReceiveWithTimeout(c Conn, timeout time.Duration) (interface{}, error)

​ 带超时的receive函数,获取redis结果

16 func Scan(src []interface{}, dest ...interface{}) ([]interface{}, error)

· 从src扫描副本到dest指向的值。即是, 将结果逐一赋予对应的变量
· dest指向的值必须是整数,浮点数,布尔值,字符串,[]字节,接口{}或这些类型的切片。Scan使用标准的strconv包将批量字符串转换为数字和布尔类型。
· 如果dest值为nil,则跳过相应的src值。
· 如果src元素为nil,则不修改相应的dest值。为了能够在循环中轻松使用Scan,Scan会根据复制的值返回src片

17 func ScanSlice(src []interface{}, dest interface{}, fieldNames ...string) error

​ ScanSlice将src扫描到dest指向的切片。dest切片的元素必须是整数,浮点数,布尔值,字符串,结构或指向struct值的指

18 func ScanStruct(src []interface{}, dest interface{}) error

​ ScanStruct将src中的名称和值交替扫描到结构中

19 func String(reply interface{}, err error) (string, error)

​ 转换为string

​ 类型转换规则

Reply type      Result
bulk string     string(reply), nil
simple string   reply, nil
nil             "",  ErrNil
other           "",  error

​ 例如:

c, err := dial()
if err != nil {
    fmt.Println(err)
    return
}
defer c.Close()

c.Do("SET", "hello", "world")
s, err := redis.String(c.Do("GET", "hello"))
fmt.Printf("%#v\n", s)

20 func StringMap(result interface{}, err error) (map[string]string, error)

​ 转换为map [string]

21 func Strings(reply interface{}, err error) ([]string, error)

​ 转换为sting 切片 []string

22 func Uint64(reply interface{}, err error) (uint64, error)

​ 转换为无符号的int64类型

23 func Values(reply interface{}, err error) ([]interface{}, error)

​ 将一组命令结果转换为 []interface{}。如果err不等于nil,那么Values返回nil,err

​ 转换规则

Reply type      Result
array           reply, nil
nil             nil, ErrNil
other           nil, error

比如:

r, err := redis.Values(c1.Do("EXEC"))

Do传参Args

定义:type Args []interface{}

为了能够方便地传入多个参数:

例如:

c, err := dial()
if err != nil {
    fmt.Println(err)
    return
}
defer c.Close()

var p1, p2 struct {
    Title  string `redis:"title"`
    Author string `redis:"author"`
    Body   string `redis:"body"`
}

p1.Title = "Example"
p1.Author = "Gary"
p1.Body = "Hello"

if _, err := c.Do("HMSET", redis.Args{}.Add("id1").AddFlat(&p1)...); err != nil {
    fmt.Println(err)
    return
}

m := map[string]string{
    "title":  "Example2",
    "author": "Steve",
    "body":   "Map",
}

if _, err := c.Do("HMSET", redis.Args{}.Add("id2").AddFlat(m)...); err != nil {
    fmt.Println(err)
    return
}

for _, id := range []string{"id1", "id2"} {

    v, err := redis.Values(c.Do("HGETALL", id))
    if err != nil {
        fmt.Println(err)
        return
    }

    if err := redis.ScanStruct(v, &p2); err != nil {
        fmt.Println(err)
        return
    }

    fmt.Printf("%+v\n", p2)
}

输出:

{Title:Example Author:Gary Body:Hello}
{Title:Example2 Author:Steve Body:Map}
 类似资料: