I'm trying to get better at using interfaces in Go to describe specific functionality, and using interface composition to write better, more understandable code. I ran into this problem which seems like it would be a common use case of go interfaces, yet I can't seem to figure out the proper syntax to use for this application. Here's some code to help explain what I am trying to do:
// Initializable is an interface to an object that can be initialized.
type Initializable interface {
Initialize() error
}
// InitializeAll initializes an array of members.
func InitializeAll(members []Initializable) error {
for _, member := range members {
err := member.Initialize()
if err != nil {
return err
}
}
return nil
}
// Host is an interface to an object providing a set of handlers for a web host.
type Host interface {
Initializable
Hostname() string
RegisterHandlers(router *mux.Router)
}
// ConfigureHosts configures a set of hosts and initializes them.
func ConfigureHosts(hosts []Host) (*mux.Router, error) {
err := InitializeAll(hosts) // compiler error here
}
This is the error: cannot use hosts (type []Host) as type []Initializable in argument InitializeAll
.
My initial thought was that I was missing some sort of type downcast, which I know works for single interface objects, but had difficulty casting an array. When I tried doing err := InitializeAll(hosts.([]Initializable))
, I got the following error: invalid type assertion: hosts.([]Initializable) (non-interface type []Host on left)
.
I'd appreciate any ideas as it comes to the design of this code example, and perhaps any suggestions as to proper syntax or some refactoring that I could do to solve this problem. Thanks!