我有一个看起来像这样的结构:
type authEnum int const ( never authEnum = iota sometimes always ) type Attrs struct { Secret string `redis:"secret"` RequireSecret authEnum `redis:"requireSecret"` UserID string `redis:"userId"` } func (e *authEnum) RedisScan(src interface{}) error { // This never gets called! if e == nil { return fmt.Errorf("nil pointer") } switch src := src.(type) { case string: if src == "false" || src == "never" { *e = never } else if src == "sometimes" { *e = sometimes } else { // "always" or "true" *e = always } default: return fmt.Errorf("cannot convert authEnum from %T to %T", src, e) } return nil } func getAttributes(ctx *AppContext, hash string) (*Attrs, error) { rc := ctx.RedisPool.Get() values, err := redis.Values(rc.Do("HGETALL", "redishash")) rc.Close() if err != nil { return nil, err } attrs := Attrs{} redis.ScanStruct(values, &attrs) return &attrs, nil }
如何实现扫描仪的接口RequireSecret属性来解析authEnum类型超出"never","sometimes"或"always"Redis的哈希值?
RequireSecret
authEnum
"never"
"sometimes"
"always"
如何计算值并将其分配给authEnum?在我的代码示例中,RedisScan永远不会调用。
RedisScan
在指针接收器上实现该方法。Redis批量字符串表示为[] byte,而不是字符串:
func (e *authEnum) RedisScan(src interface{}) error { b, ok := src.([]byte) if !ok { return fmt.Errorf("cannot convert authEnum from %T to %T", src, b) } switch string(b) { case "false", "never": *e = never case "sometimes": *e = sometimes default: *e = always } return nil }
始终检查并处理错误。从返回的错误ScanStruct报告类型问题。
ScanStruct
无需检查指向struct成员的nil指针。如果ScanStruct的参数为nil,则Redigo将在调用RedisScan方法之前恐慌。