我有一个看起来像这样的结构:
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
属性上实现Scanner接口(interface),以从authEnum
,"never"
或"sometimes"
redis哈希值中解析出"always"
类型?如何计算值并将其分配给authEnum?
在我的代码示例中,
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
返回的错误报告类型问题。无需检查指向struct成员的nil指针。如果ScanStruct的参数为nil,则Redigo将在调用RedisScan方法之前 panic 。