【问题标题】:Golang - add "inheritance" to structsGolang - 向结构添加“继承”
【发布时间】:2016-09-20 12:33:11
【问题描述】:

我想优化我的代码,然后我有以下情况:

我有一个通用的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
}

那么,是否可以在结构中定义一个字段(更准确地说是Cache.memory_cache),当声明发生时可以进一步定义,而不使用interface

【问题讨论】:

    标签: go struct interface


    【解决方案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
    }
    

    【讨论】:

      【解决方案2】:

      我认为结构嵌入是您要寻找的主要内容:

      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 方法,则该接口将被实现。

      仍然有相当多的样板,但这减少了结构定义中的冗余问题。如果您不想键入样板,可以使用代码生成工具。

      【讨论】:

      • +1 感谢您的回复并显示我所问问题的另一种可能的解决方案。我刚刚接受了@Not_a_Golfer 的另一个答案,因为它更符合我的“代码风格”。但正如所说,这将是另一个很好的解决方案,如果我可以选择两个答案,我会选择两个;-)
      猜你喜欢
      • 2011-06-16
      • 1970-01-01
      • 2014-02-25
      • 2015-11-18
      • 2013-06-24
      • 2017-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多