类型断言恐慌
Type-assertion panic
我想在我的代码上应用依赖注入,所以我将它的每个部分都创建为服务。
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
当您从函数 return 一个 BaseInterface
时,引用的类型实际上是 BaseInterface
而不是 SetupService
。确实 SetupService
确实满足 BaseInterface
,但是当你转换时类型信息丢失了。
你可以这样做:
func (s SetupService) Set() SetupService {
s.BaseService.Set()
return s
}
但要注意的一件事是您没有使用指针,因此每个方法调用都会复制对象,并且不会保留状态突变。您可能想要替换这些:
func (s SetupService) ...
有了这些:
func (s *SetupService) ...
更新:为什么不直接避免return在此处设置 Set 的结果?
s := SetupService{}
s.Set(...)
return s
我想在我的代码上应用依赖注入,所以我将它的每个部分都创建为服务。
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
当您从函数 return 一个 BaseInterface
时,引用的类型实际上是 BaseInterface
而不是 SetupService
。确实 SetupService
确实满足 BaseInterface
,但是当你转换时类型信息丢失了。
你可以这样做:
func (s SetupService) Set() SetupService {
s.BaseService.Set()
return s
}
但要注意的一件事是您没有使用指针,因此每个方法调用都会复制对象,并且不会保留状态突变。您可能想要替换这些:
func (s SetupService) ...
有了这些:
func (s *SetupService) ...
更新:为什么不直接避免return在此处设置 Set 的结果?
s := SetupService{}
s.Set(...)
return s