2016-09-20 50 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