go - 在结构的字段上实现 Redigo Scanner 接口(interface)

标签 go redis redigo

我有一个看起来像这样的结构:

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
}

我如何实现 Scanner RequireSecret 属性上的接口(interface),用于解析“never”“sometimes” 中的 authEnum 类型>“总是” redis 哈希值?

如何计算值并将其分配给 authEnum? 在我的代码示例中,RedisScan 永远不会被调用。

最佳答案

您不在字段上实现接口(interface),而是在类型上实现接口(interface)。

您可以让您的 authEnum 类型满足接口(interface),只需在该类型上创建一个带有签名 RedisScan(src interface{}) error 的方法即可。

要赋值给接收者,需要接收一个指针。然后你可以这样分配给它:

func (e *authEnum) RedisScan(src interface{}) error {
    var value authEnum
    // Logic here to convert src to value
    *e = value
}

关于go - 在结构的字段上实现 Redigo Scanner 接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46911105/

相关文章:

go lang version-able 字符串规范化

go - 如何在beego中获取controller之外的cookie和session

linux - Redisused_memory_rss 大于配置集 'maxmemory' 吗?

Redis多种持久化策略

mysql - Vanity 不适用于 MySql

go - Redigo 多请求

go - Go中如何实现虚继承

directory - Go语言如何检查zip入口是否为目录

go - 如何使用 redigo 库从 golang 查询 Redis 数据库

docker - redis:调用 tcp [REDIS ADDRESS] connect:连接被拒绝