What I'm trying to do is to create a slice of an interface
type and populating it with some struct types that are implementing this interface.
chans := []chan Event {
make(chan FileEvent),
make(chan NetworkEvent),
}
But this fails with cannot use make(chan FileEvent) (type chan FileEvent) as type chan Event in array or slice literal
.
Now I am aware that this is meant to be that way.
However the suggested solution is a) not practical because I have a bunch of different types and cannot easily iterate over them and b) I cannot even get it to work, it still gives me the same error. I tried:
chans := make([]chan Event, 2)
chans[0] = make(chan FileEvent)
Do you guys know what I'm doing wrong or how this can be solved elegantly? Thanks a lot !!
Here are the definitions of the types:
type Event interface {
GetId() string
}
type FileEvent struct {
}
func (e FileEvent) GetId() string {
return "FileEvent"
}
Event
may be an interface type, but chan Event
is not; it is a specific channel type. A []chan Event
is a slice, in which every element must be of type chan Event
. However, a chan Event
could accept messages of any type implementing Event
.
Why? Consider this code:
chans := []chan Event {
make(chan FileEvent),
make(chan NetworkEvent),
}
ch := chans[0] // ch is of type chan Event because that's the type of elements of chans
ch <- NetworkEvent{} // Uh oh - we just tried to send a NetworkEvent to what's actually a chan FileEvent!
The send would be compile-time legal if your code were legal, but would cause a runtime type error, which is not allowed in Go as it uses strict static typing.
You could, however, make them all chan Event
, and then you could send whatever types you needed, and use type assertions when receiving from those channels.