首页 > 解决方案 > 使用接口时检查变量类型是否为零

问题描述

我有一个缓存对象的接口,它lru从以下镜像缓存github.com/hashicorp/golang-lru

type Cacher interface {
    Add(key, value interface{})
    Get(key interface{}) (value interface{}, ok bool)

}

main.go满足某些条件时创建对象,否则它保持为空:

import lru "github.com/hashicorp/golang-lru"
...
var cache *lru.ARCCache
if someCondition {
    cache, _ = lru.NewARC(int(cacheSize))
}

... later on
r.Cache = cache

现在,在另一个包中,我在对其进行任何操作之前检查缓存是否为零:

if r.Cache != nil {
    v, found := r.Cache.Get(...)
}

这会导致invalid memory address or nil pointer dereference 错误,因为类型不是 nil 但值是。

我的问题是如何检查是否r.Cache为 nil 而不必导入github.com/hashicorp/golang-lru该包(这使得使用Cacher接口毫无意义):if r.Cache != (*lru.ARCCache)(nil)

标签: if-statementgonulltypechecking

解决方案


避免检查接口中的 nil 具体值,因为 nil 值可能是接口的有效实现。这是一个有点人为的例子,说明 nil 有效的地方:

type exampleCacher struct { }

func (c *exampleCacher) Get(key interface{}) (value interface{}, ok bool) }
   if c == nil {
      return nil, false
   }
   ...
}

解决此问题的更好方法是确保代码仅将有效值分配给r.Cache.

问题中的代码始终设置r.Cache为非零值,因为代码将具体类型分配给r.Cache. 有关解释,请参阅关于 nil 错误的常见问题解答条目

通过声明cacheCacher.

var cache Cacher

正如我在上面的评论中提到的,另一个解决方法是:

if cache != nil { 
   r.Cache = cache 
}

推荐阅读