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
可以通过跳转看到函数内部实现如下

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

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

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

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

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

忽略头部的睡眠代码,直接下面
c.withConn 传递了一个匿名函数,在方法中获取到一个 conn 对象,然后调用该函数

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

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

最终兜底处理

Summary
go-redis 库对于 HSet 方法支持的数据类型为 interface{},在传递数据时会调用 writeCmd 方法进行序列化处理,最终通过 conn 对象将数据传递给 redis 服务端
支持的数据类型基本为基础数据类型,如果是自定义的结构体需要自己实现序列化和反序列化的方式

浙公网安备 33010602011771号