larksuite/oapi-sdk-go

Cache接口的Set方法的value参数的类型能否用interface{}呢?

passion-8023 opened this issue · 0 comments

飞书SDK的 Cache接口:

type Cache interface {
	Set(ctx context.Context, key string, value string, expireTime time.Duration) error
	Get(ctx context.Context, key string) (string, error)
}

GO语言的 redis包 github.com/go-redis/redis/v8
Set 方法的参数 value 使用的是 interface{} 类型

  func (c cmdable) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *StatusCmd {
	  args := make([]interface{}, 3, 5)
	  args[0] = "set"
	  args[1] = key
	  args[2] = value
	  if expiration > 0 {
		  if usePrecise(expiration) {
			  args = append(args, "px", formatMs(ctx, expiration))
		  } else {
			  args = append(args, "ex", formatSec(ctx, expiration))
		  }
	  } else if expiration == KeepTTL {
		  args = append(args, "keepttl")
	  }
  
	  cmd := NewStatusCmd(ctx, args...)
	  _ = c(ctx, cmd)
	  return cmd
  }

所以在开发的时候,大多数企业或者个人都会封装自己的go-kit工具,统一去定义 Cache接口,然后用redis去实现 Cache接口

/ Cache 缓存相关的实现 .
type Cache interface {
	// Set .
	Set(ctx context.Context, key string, value interface{}, expiration time.Duration) error

	// Get .
	Get(ctx context.Context, key string) (string, error)
}

为了方便大多数项目可能就直接用 interface{} 类型和 redis包保持一致了

func (r *Redis) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) error {
	err := r.client.Set(ctx, key, value, expiration).Err()
	return err
}

func (r *Redis) Get(ctx context.Context, key string) (string, error) {
	value, err := r.client.Get(ctx, key).Result()
	if err != nil && err == redis.Nil {
		return "", errors.ERRMissingCacheKey
	}
	return value, nil
}

然而当我项目用到飞书SDK的时候,我想定制 token 缓存器,使用我已有的redis作为SDK的缓存器,就无法使用,因为我没有实现SDK提供的Cache接口的Set方法
image

当我去实现SDK提供的 Cache接口时,报重名错误

截屏2023-03-24 15 24 11

其实SDK完全也可以使用 interface{}类型,这样就避免了类型不一致而方法同名的情况了