redis.ScanStruct 函数和 Args.AddFlat 方法缺少使该对可用作通用编组/解组函数的功能。
解决问题的方法取决于您的目标。
如果您的目标是加载和保存结构,而不是访问 Redis 哈希,请参阅 Save generic struct to redis。
如果您的目标是使用已定义的名称和值访问 Redis 哈希,则编写在这些定义和 Go 值之间进行转换的代码。下面是一个散列示例,该散列定义为具有字段“timestamp”,其值为十进制编码的 Unix 秒:
type Data struct {
Timestamp time.Time
}
func (r *RedisRepo) Write(data Data, key string) error {
conn := r.pool.Get()
defer conn.Close()
_, err := conn.Do("HSET", key, "timestamp", data.Timestamp.Unix())
return err
}
func (r *RedisRepo) Read(key string) (*Data, error) {
conn := r.pool.Get()
defer conn.Close()
v, err := redis.Values(conn.Do("HGETALL", key))
if err != nil {
return nil, err
}
var fields struct {
Timestamp int64 `redis:"timestamp"`
}
err = redis.ScanStruct(v, &fields)
if err != nil {
return nil, err
}
return &Data{Timestamp: time.Unix(fields.Timestamp, 0)}, nil
}
根据需要调整代码以匹配 Redis 哈希字段定义。这是RFC 3339格式的时间代码:
type Data struct {
Timestamp time.Time
}
func (r *RedisRepo) Write(data Data, key string) error {
conn := r.pool.Get()
defer conn.Close()
_, err := conn.Do("HSET", key, "timestamp", data.Timestamp.Format(time.RFC3339))
return err
}
func (r *RedisRepo) Read(key string) (*Data, error) {
conn := r.pool.Get()
defer conn.Close()
v, err := redis.Values(conn.Do("HGETALL", key))
if err != nil {
return nil, err
}
var fields struct {
Timestamp string `redis:"timestamp"`
}
err = redis.ScanStruct(v, &fields)
if err != nil {
return nil, err
}
t, err := time.Parse(time.RFC3339, fields.Timestamp)
if err != nil {
return nil, err
}
return &Data{Timestamp: t}, nil
}
上面的Read 示例是这样编写的,以便示例易于扩展到多个字段。如果应用程序只需要访问单个字段,请将fields 变量和ScanStruct 废话替换为对redis.Int64(conn.Do("HGET", key, "timestamp") 或redis.String(conn.Do("HGET", key, "timestamp") 的调用