猿问

使用接口时检查变量类型是否为零

我有一个缓存对象的接口,它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)


千万里不及你
浏览 161回答 2
2回答

暮色呼如

避免检查接口中的 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 错误的常见问题解答条目。通过声明cache为Cacher.var cache Cacher正如我在上面的评论中提到的,另一个解决方法是:if cache != nil {    r.Cache = cache }

HUWWW

请注意(*lru.ARCCache)(nil) != Cacher(nil)。所以不要分配(*lru.ARCCache)(nil)给r.Cache.这是修复:if cache != nil {    r.Cache = cache}
随时随地看视频慕课网APP

相关分类

Go
我要回答