2017-05-24 200 views
0

我想申请依赖注入我的代码,所以我创建它的每个部分作为服务。类型断言恐慌

type BaseService struct { 
    Config config.Container 
    SQL *gorm.DB 
    Mongo *mgo.Session 
    Logger logger.Logger 
} 

type BaseInterface interface { 
    Set(c config.Container, sq *gorm.DB, m *mgo.Session, l logger.Logger) BaseInterface 
} 

func (s BaseService) Set(c config.Container, sq *gorm.DB, m *mgo.Session, l logger.Logger) BaseInterface { 
    s.Config = c 
    s.SQL = sq 
    s.Mongo = m 
    s.Logger = l 
    return s 
} 

func NewSetupService(c config.Container, s *gorm.DB, m *mgo.Session, l logger.Logger) SetupService { 
    return SetupService{}.Set(c, s, m, l).(SetupService) 
} 
... 
... 

还有就是BaseService和每个服务将其扩展为如下:

type SetupService struct { 
    BaseService 
} 

type SetupInterface interface { 
    Do() 
} 

func (s SetupService) Do() { 
    mongo := s.Mongo.Clone() 
    defer mongo.Close() 
    mongoDB := mongo.DB(s.Config.Database.Mongo.DB) 
... 
... 

但当我致电NewSetupService功能我得到了恐慌,让人听不清楚我。基本上我创建一个SetupService {}并调用这个结构体的Set函数,对吗?那么,为什么我得到这个恐慌:

panic: interface conversion: api.BaseInterface is api.BaseService, not api.SetupService [recovered] 
    panic: interface conversion: api.BaseInterface is api.BaseService, not api.SetupService 

回答

3

当你从一个函数返回一个BaseInterface,参考的类型实际上BaseInterface,而不是SetupService是。确实SetupService确实满足BaseInterface,但是在投射时该类型信息会丢失。

你可以做的是这样的:

func (s SetupService) Set() SetupService { 
    s.BaseService.Set() 
    return s 
} 

但有一件事要注意的是,你不使用指针,所以每个方法调用复制对象和状态突变不会保留。您可能要替换这些:

func (s SetupService) ... 

有了这些:

func (s *SetupService) ... 

更新:为什么不避免返回此处设置的结果呢?

s := SetupService{} 
s.Set(...) 
return s 
+0

Go没有继承的概念 - 不知道你是什么意思或我自己编辑答案。 – Adrian

+0

谢谢。它解决了我的问题,但由于额外的一项功能/每项服务,我感到很难过。 – PumpkinSeed

+0

@阿德里安:我们在这里分开毛发,但我会重新措辞,以便它在学术上是正确的。 – robbrit