我有一个缓存对象的接口(interface),它镜像 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
error因为类型不是 nil 但值是。我的问题是如何检查
r.Cache
为 nil 而无需导入 github.com/hashicorp/golang-lru
在那个包中(这使得使用 Cacher
接口(interface)毫无意义):if r.Cache != (*lru.ARCCache)(nil)
最佳答案
避免检查接口(interface)中的 nil 具体值,因为 nil 值可能是接口(interface)的有效实现。这是一个有点人为的例子,说明 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
.见FAQ entry on nil error解释一下。通过声明
cache
来解决问题作为 Cacher
.var cache Cacher
正如我在上面的评论中提到的,另一个解决方法是:
if cache != nil {
r.Cache = cache
}
关于if-statement - 使用接口(interface)时检查变量类型是否为零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61092286/