duanbangzhou7809 2017-05-24 18:55
浏览 25
已采纳

类型断言恐慌

I would like to apply Dependency injection on my code so I create every part of it as a service.

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)
}
...
...

There is the BaseService and every service extend it as the follow:

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)
...
...

But when I call the NewSetupService function I got a panic which is not clear for me. Basically I create a SetupService{} and call the Set function of this struct, am I right? Then why I got this panic:

panic: interface conversion: api.BaseInterface is api.BaseService, not api.SetupService [recovered]
    panic: interface conversion: api.BaseInterface is api.BaseService, not api.SetupService
  • 写回答

1条回答 默认 最新

  • duancan65665 2017-05-24 19:01
    关注

    When you return a BaseInterface from a function, the type of the reference is actually BaseInterface and not SetupService. It is true that SetupService does satisfy BaseInterface, but that type information is lost when you cast.

    What you could do is this:

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

    One thing to note though is that you're not using pointers, so each method call copies the object and state mutations are not preserved. You might want to replace these:

    func (s SetupService) ...
    

    With these:

    func (s *SetupService) ...
    

    Update: Why not just avoid returning the result of Set here?

    s := SetupService{}
    s.Set(...)
    return s
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 python天天向上类似问题,但没有清零
  • ¥30 3天&7天&&15天&销量如何统计同一行
  • ¥30 帮我写一段可以读取LD2450数据并计算距离的Arduino代码
  • ¥15 C#调用python代码(python带有库)
  • ¥15 矩阵加法的规则是两个矩阵中对应位置的数的绝对值进行加和
  • ¥15 活动选择题。最多可以参加几个项目?
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型
  • ¥15 vs2019中数据导出问题
  • ¥20 云服务Linux系统TCP-MSS值修改?
  • ¥20 关于#单片机#的问题:项目:使用模拟iic与ov2640通讯环境:F407问题:读取的ID号总是0xff,自己调了调发现在读从机数据时,SDA线上并未有信号变化(语言-c语言)