2016-09-20 53 views
1

我想优化我的代码,我有那么下面的情况:Golang - 添加“继承”,以结构

我有一个大致的struct只有一个域给出了规范,让说缓存结构例如:

# the main cache struct 
type Cache struct { 
    name    string 
    memory_cache  map[string]interface{} 
    mutex   *sync.Mutex 
    ...    ... 
    # common fields 
} 

# an element stored in the Cache.memory_cache map 
type ElementA { 
    name string 
    count int64 
} 

# an element stored in the Cache.memory_cache map 
type ElementB { 
    name string 
    tags []string 
} 

我目前的解决方案遵循先前的定义,我为每一个元素的缓存(它必须是这样:每个元素的一个缓存):

var cache_for_element_A Cache{} 
var cache_for_element_B Cache{} 

但是在这种方式下,即使我已经知道什么是内容(当时不需要投射案例),我也必须在阅读时始终投下memory_cache


下面的代码做我想有什么,但它定义了两次了很多赘余力/公共领域,因为这个原因,我想寻找另一种解决方案。

type CacheForA struct { 
    name    string 
    memory_cache  map[string]ElementA{} 
    mutex   *sync.Mutex 
    ...    ... 
    # common fields 
} 

type CacheForB struct { 
    name    string 
    memory_cache  map[string]ElementB{} 
    mutex   *sync.Mutex 
    ...    ... 
    # common fields 
} 

然后,是有可能在能够进一步当声明发生和定义,而无需使用interface的结构(更精确地Cache.memory_cache)来定义一个字段?

回答

1

Go没有泛型,所以没有简单的方法来做到这一点,就像在Java中一样(class Cache<T>()....)。

你可以做的一件事就是用一个小型函数包装你的缓存,只需从通用缓存中提取对象并将接口转换为正确的类型。这样可以避免在代码中反复写入接口转换。

type ElemACache struct { 
    Cache 
} 

func (c *ElemeACache)Get(key string) ElemeA { 
    return c.Cache.Get(key).(ElemeA) //of course add checks here 
} 
1

结构嵌入是你正在寻找我主要的事情想:

type Cache struct { 
    name    string 
    mutex   *sync.Mutex 
} 

type CacheA struct { 
    Cache 
    memory_cache map[string]ElementA{} 
} 

然后你犯了一个类型的接口,说有一组的,你需要做的事情的方法“cacher的”你的各种缓存(cacheA,CacheB)。创建CacheA,CacheB这些方法,并且只需要只返回类型断言:

type Cacher interface { 
    GetItem(string) (interface{}, error) 
} 

如果所有CacheFor类型具有的GetItem方法,该接口将得到满足。

仍然有相当数量的样板,但这样可以减少结构定义中的冗余问题。如果你不想输入锅炉板,有代码生成工具。

+0

+1感谢您的回复并显示了我所问的其他可能解决方案。我刚刚接受了@Not_a_Golfer的另一个答案,因为它跟随了一种更好的'代码风格'。但正如所说,这将是另一个伟大的解决方案,如果我可以选择两个答案,我会选择两个;-) – damoiser