I'm trying to break circular dependencies in a reasonably sized golang project by using interfaces. I have some nested structs like this:
// these are in one package...
type config struct {
region string
}
type system struct {
name string
config config
}
func (s system) getName() string {
return s.name
}
func (s system) getConfig() config {
return s.config
}
func (c config) getRegion() string {
return c.region
}
And in another package that wants to use them I'm declaring some corresponding nested interfaces:
type iConfig interface {
getRegion() string
}
type iSystem interface {
getName() string
getConfig() iConfig
}
// and has functions like
func New(system iSystem) {
fmt.Printf("region=%s", system.getConfig().getRegion())
}
But when I try to use them like this:
theSystem := system{
name: "testName",
config:config{
region:"testRegion",
},
}
New(theSystem) // doesn't work
I get an error:
cannot use theSystem (type system) as type iSystem in argument to New:
system does not implement iSystem (wrong type for getConfig method)
have getConfig() config
want getConfig() iConfig
It seems that because my concrete system struct returns a concrete type config Go doesn't think it satisifes the iConfig interface - even though I can use config via the iConfig interface directly. I was expecting config to implicitly satisfy the iConfig interface but that's not happening. How can I fix this?
Here's a link to the Go Playground.
configto implicitly satisfy theiConfiginterface but that's not happening." That is actually what is happening, but just becauseconfigimplementsiConfigthat doesn't mean thatsystemimplementsiSystem, the method signatures are different and that is the reason why you're getting the error. The error message is pretty clear about that with thehavevswantexplanation. To fix it, you can update the signature of thesystem'sgetConfigmethod to return the interface instead of the concrete type.