Golang 库 Redis 对 data 类型的支持

go-redis 库对于 HSet 方法支持的数据类型为 interface{}, 查看下支持哪些类型的

Version

github.com/go-redis/redis/v8 v8.11.5

https://pkg.go.dev/github.com/go-redis/redis/v8@v8.11.5#Client.HSet

Code

type Son struct {
    A int
    B string
}

type Person struct {
    Name string
    Age  int
    Son  []Son
}

func TestSerialize(t *testing.T) {
    redis := redis.NewClient(&redis.Options{
        Addr: "localhost:6379",
    })

    data := Person{
        Name: "zhangsan",
        Age:  18,
        Son: []Son{
            {
                A: 1,
                B: "a",
            },
            {
                A: 2,
                B: "b",
            },
        },
    }

    redis.HSet(context.Background(), "person", "name", data)
}

Debug

可以通过跳转看到函数内部实现如下

HSet code

appendArgs 函数将 args 追加到 values 参数的前面后生成一个 IntCmd 对象,传递给 c 进行处理(c的定义可以在 NewClient 函数中看到其为 Client 对象)

NewClient Code

通过调试追踪可以确认 cClient 对象,cProcess 方法会将 IntCmd 对象传递给 Process 方法进行处理

alt text

继续查看 process 方法的实现,可以看到跳到了这里

process code

由于没有设置 hook 所以直接进入 c.baseClient.process 方法执行

baseClient process code

这部分进行重复尝试,进入 c._process 方法查看代码

real code

忽略头部的睡眠代码,直接下面

c.withConn 传递了一个匿名函数,在方法中获取到一个 conn 对象,然后调用该函数

exec hand

withConn 通过传递过来的 fn 函数对数据进行序列化处理

alt text

序列化的具体实现可以发现是调用 writeCmd 方法,进入该方法一路跳转可以看到具体的执行代码

alt text

最终兜底处理

alt text

Summary

go-redis 库对于 HSet 方法支持的数据类型为 interface{},在传递数据时会调用 writeCmd 方法进行序列化处理,最终通过 conn 对象将数据传递给 redis 服务端

支持的数据类型基本为基础数据类型,如果是自定义的结构体需要自己实现序列化和反序列化的方式

posted @ 2024-07-17 10:00  Sonui  阅读(4)  评论(0编辑  收藏  举报