[英]Implementing Redigo Scanner interface on a struct's field
我有一個看起來像這樣的結構:
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接口,以從"never"
, "sometimes"
或"always"
redis哈希值中解析authEnum
類型?
如何計算值並將其分配給authEnum? 在我的代碼示例中,從未調用過RedisScan
。
您不在字段上實現接口,而是在類型上實現接口。
您可以通過創建一個authEnum
類型帶有簽名RedisScan(src interface{}) error
的方法,使authEnum
類型滿足該接口。
要分配給接收者,您需要接收一個指針。 然后,您可以按以下方式為其分配:
func (e *authEnum) RedisScan(src interface{}) error {
var value authEnum
// Logic here to convert src to value
*e = value
}
在指針接收器上實現該方法。 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方法之前恐慌。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.