The go spec states:
A variable of interface type can store a value of any type with a method set that is any superset of the interface.
As such I can
type Source interface{}
type SourceImpl struct{}
var s Source
g := new(interface{})
s = new(SourceImpl)
*g = s
However, I cannot to the same with maps:
generic := make(map[string]*interface{})
specific := make(map[string]*Source)
generic = specific
gives:
cannot use specific (type map[string]*Source) as type map[string]*interface {} in assignment
Why is that? Can map of specific types be passed/assigned to map of generic types without using type assertion?
Because map[]interface{}
and map[]SpecificInterface
are 2 different types. If you make your generic type as an empty interface it can work.
var generic interface{}
specific := make(map[string]*Source)
generic = specific
But if you do so, you need to do some type switch or type assertion, when you want to work with your map.
Because Go is a static type language , although interface{} and Source have the same underlying type , they can't be assigned to one another without a conversion.
Thus you have to do a conversion in a loop :
generic := make(map[string]interface{})
specific := make(map[string]*Source)
for k, v := range specific {
generic[k] = v
}
Did you notice I changed *interface{} to interface{} ? That's another problem of your code , in Go pointer to interface{} has not meaning.
While not directly answering the question it seems that the go community is slowly starting changing its mind and started thinking about supporting generics for Go2: https://go.googlesource.com/proposal/+/master/design/go2draft-generics-overview.md