该redis.ScanStruct
函数和该Args.AddFlat
方法缺少使该对可用作通用编组/解组函数的功能。
解决问题的方法取决于您的目标。如果您的目标是加载和保存结构,而不是访问 Redis 哈希,请参阅将通用结构保存到 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")