Golang 庫 Redis 對 data 型別的支援

Sonui發表於2024-07-17

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 服務端

支援的資料型別基本為基礎資料型別,如果是自定義的結構體需要自己實現序列化和反序列化的方式

相關文章