interface method 返回 interface 如何實現?

zensh發表於2016-10-17

需求來自於 https://github.com/teambition/ratelimiter-go 這個庫,它是基於 redis 實現的介面速率控制。

當前的實現會顯示的依賴 "gopkg.in/redis.v5" ,我希望去掉這個顯示的依賴,通過 interface 來定義需要的 redis 介面,從而可以支援 v3, v4, v5 等不同的版本,甚至其它 redis 實現(只要實現了定義的 interface)。

目前存在的問題就是 interface method 返回 interface 的問題:

type redisResult interface {
    Result() (interface{}, error)
}

type baseRedisClient interface {
    Del(...string) redisResult
    ScriptLoad(string) redisResult
    EvalSha(string, []string, ...interface{}) redisResult
}

具體程式碼詳見 https://github.com/teambition/ratelimiter-go/blob/dev/ratelimiter.go#L36

這個目前會報錯:

➜  ratelimiter-go git:(dev) go test
# github.com/teambition/ratelimiter-go_test
./example_test.go:19: cannot use client (type *redis.Client) as type ratelimiter.redisClient in argument to ratelimiter.New:
    *redis.Client does not implement ratelimiter.redisClient (wrong type for Del method)
        have Del(...string) *redis.IntCmd
        want Del(...string) ratelimiter.redisResult
...

google 了一把,有這樣一個答案:How to implement interface method with return type is an interface in Golang ,但這個解決不了我的需求,因為它要修改 method 實現方的程式碼。


最終放棄了上面這種實現方式,而是由使用者來實現 RedisClient interface,通過這種方式來支援不同版本不同實現的 redis client。

type RedisClient interface {
    RateDel(string) error
    RateEvalSha(string, []string, ...interface{}) (interface{}, error)
    RateScriptLoad(string) (string, error)
}
更多原創文章乾貨分享,請關注公眾號
  • interface method 返回 interface 如何實現?
  • 加微信實戰群請加微信(註明:實戰群):gocnio

相關文章