概要
前回 redigo の基本的な使い方を紹介しました
redis を使っていると複雑な構造を持つデータを格納したくなります
今回は redigo で階層的な構造体を扱う方法を紹介します
環境
- CentOS 7.6.1810
- go 1.12.1
- redigo d3876d43bbbeb98b4d67309b4d3eef49438ef74c
結論
ハッシュを使って ScanStruct
で構造体にマッピングすることはできないようです
https://github.com/gomodule/redigo/issues/52
結論としては JSON 文字列を set し取り出すときは get でまず文字列として取り出しそれを構造体にマッピングします
以下サンプルコードです
サンプルコード
package main
import (
"encoding/json"
"fmt"
"github.com/gomodule/redigo/redis"
"math"
"time"
)
type Profile struct {
Name string `json:"name"`
Age int `json:"age"`
Address Address `json:"address"`
Test Test `json:"test"`
CreatedAt time.Time `json:"created_at"`
}
type Address struct {
Zip string `json:"zip"`
City string `json:"city"`
}
type Test struct {
I64 int64 `json:"i64"`
F64 float64 `json:"f64"`
}
func main() {
c, err := redis.Dial("tcp", "localhost:6379")
if err != nil {
fmt.Println(err)
return
}
defer c.Close()
// nested struct
p := Profile{
Name: "hawksnowlog",
Age: 99,
Address: Address{
Zip: "123-4567",
City: "123-4567",
},
Test: Test{
I64: math.MaxInt64,
F64: math.MaxFloat64,
},
CreatedAt: time.Now(),
}
// to json
j, err := json.Marshal(p)
if err != nil {
fmt.Println(err)
return
}
// debug print a json string
fmt.Println(string(j))
// set a json string
_, err = c.Do("set", "profile", j)
if err != nil {
fmt.Println(err)
return
}
// get a json string as bytes
j2, err := redis.Bytes(c.Do("get", "profile"))
if err != nil {
fmt.Println(err)
return
}
// bytes json to struct
p2 := Profile{}
err = json.Unmarshal(j2, &p2)
if err != nil {
fmt.Println(err)
return
}
// debug print struct fields
fmt.Println(p2.Name)
fmt.Println(p2.Age)
fmt.Println(p2.Address.Zip)
fmt.Println(p2.Address.City)
fmt.Println(p2.Test.I64)
fmt.Println(p2.Test.F64)
fmt.Println(p2.CreatedAt.Day())
}
json.Marshal
は結構賢いようで time や int64, float64 もちゃんと構造体に合わせてキャストしてくれました
0 件のコメント:
コメントを投稿