[英]Implementing Redigo Scanner interface on a struct's field
I have a struct that looks like this: 我有一个看起来像这样的结构:
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
}
How do I implement the Scanner interface on the RequireSecret
attribute to parse an authEnum
type out of "never"
, "sometimes"
or "always"
redis hash values? 如何在
RequireSecret
属性上实现Scanner接口,以从"never"
, "sometimes"
或"always"
redis哈希值中解析authEnum
类型?
How do I calculate the value and assign it to the authEnum? 如何计算值并将其分配给authEnum? In my code example
RedisScan
never gets called. 在我的代码示例中,从未调用过
RedisScan
。
You don't implement interfaces on fields, but rather on types. 您不在字段上实现接口,而是在类型上实现接口。
You can make your authEnum
type satisfy the interface, simply by creating a method with the signature RedisScan(src interface{}) error
on that type. 您可以通过创建一个
authEnum
类型带有签名RedisScan(src interface{}) error
的方法,使authEnum
类型满足该接口。
To assign to the receiver, you need to receive a pointer. 要分配给接收者,您需要接收一个指针。 Then you can assign to it as so:
然后,您可以按以下方式为其分配:
func (e *authEnum) RedisScan(src interface{}) error {
var value authEnum
// Logic here to convert src to value
*e = value
}
Implement the method on a pointer receiver. 在指针接收器上实现该方法。 Redis bulk strings are represented as []byte, not string:
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
}
Always check and handle errors. 始终检查并处理错误。 The error returned from
ScanStruct
reports the type problem. 从
ScanStruct
返回的错误报告类型问题。
There's no need to check for nil pointer to the struct member. 无需检查指向struct成员的nil指针。 If the argument to ScanStruct is nil, then Redigo will panic well before the RedisScan method is called.
如果ScanStruct的参数为nil,则Redigo将在调用RedisScan方法之前恐慌。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.